Here's what a custom type might look like for this:
// Demo void main() { int[3][3] arr = [ [1, 2, 3], [4, 5, 6], [7, 8, 9], ]; // simple creation auto middleColumn = verticalSlice(arr, 1); assert(middleColumn[1] == 5); // iteratable foreach (i, v; middleColumn) assert(v == 2+i*3); // still a slice - writing will change original array middleColumn[1] = 17; assert(arr[1][1] == 17); // sliceable itself auto center = middleColumn[1..2]; center[0] = 42; assert(arr[1][1] == 42); // get a normal array with .dup int[] copyOfMiddleColumn = middleColumn.dup; } // Implementation struct StepSlice(T) { T* ptr; size_t length, step; T opIndex(size_t index) in { assert(index<length); } body { return ptr[step*index]; } void opIndexAssign(T value, size_t index) in { assert(index<length); } body { ptr[step*index] = value; } StepSlice!T opSlice(size_t start, size_t end) in { assert(start<=end && end<=length); } body { return StepSlice!T(ptr+start*step, end-start, step); } int opApply(int delegate(ref T) dg) { int result = 0; for (size_t i=0; i<length; i++) { result = dg(ptr[i*step]); if (result) break; } return result; } int opApply(int delegate(ref size_t, ref T) dg) { int result = 0; for (size_t i=0; i<length; i++) { result = dg(i, ptr[i*step]); if (result) break; } return result; } T[] dup() { T[] result = new T[length]; for (size_t i=0; i<length; i++) result[i] = ptr[i*step]; return result; } } StepSlice!T verticalSlice(T, size_t W)(T[W][] arr, size_t column) { return StepSlice!T(arr[0].ptr+column, arr.length, W); }
I think these are the missing range primitives, but still a good starting point.
From std.range.stride :
import std.range; // Demo void main() { int[3][3] arr = [ [1, 2, 3], [4, 5, 6], [7, 8, 9], ]; // simple creation auto middleColumn = verticalSlice(arr, 1); assert(middleColumn[1] == 5); // iteratable uint i; foreach (v; middleColumn) assert(v == 2+(i++)*3); // still a slice - writing will change original array middleColumn[1] = 17; assert(arr[1][1] == 17); // sliceable itself auto center = middleColumn[1..2]; center[0] = 42; assert(arr[1][1] == 42); // get a normal array with array() int[] copyOfMiddleColumn = array(middleColumn); } // Implementation auto verticalSlice(T, size_t W)(T[W][] arr, size_t column) { T* start = arr[0].ptr+column; return stride(start[0..W*arr.length], W); }