Lockstep

Iterate multiple ranges in lockstep using a foreach loop. In contrast to zip it allows reference access to its elements. If only a single range is passed in, the Lockstep aliases itself away. If the ranges are of different lengths and s == StoppingPolicy.shortest stop after the shortest range is empty. If the ranges are of different lengths and s == StoppingPolicy.requireSameLength, throw an exception. s may not be StoppingPolicy.longest, and passing this will throw an exception.

Iterating over Lockstep in reverse and with an index is only possible when s == StoppingPolicy.requireSameLength, in order to preserve indexes. If an attempt is made at iterating in reverse when s == StoppingPolicy.shortest, an exception will be thrown.

By default StoppingPolicy is set to StoppingPolicy.shortest.

struct Lockstep (
Ranges...
) if (
Ranges.length > 1 &&
allSatisfy!(isInputRange, Ranges)
) {}

Constructors

this
this(Ranges ranges, StoppingPolicy sp)

Examples

int[6] arr1 = [1,2,3,4,5,100];
int[5] arr2 = [6,7,8,9,10];

foreach (ref a, b; lockstep(arr1[], arr2[]))
{
    a += b;
}

assert(arr1 == [7,9,11,13,15,100]);

Lockstep also supports iterating with an index variable:

int[3] arr1 = [1,2,3];
int[3] arr2 = [4,5,6];

foreach (index, a, b; lockstep(arr1[], arr2[]))
{
    assert(arr1[index] == a);
    assert(arr2[index] == b);
}

See Also

zip

lockstep is similar to zip, but zip bundles its elements and returns a range. lockstep also supports reference access. Use zip if you want to pass the result to a range function.

Meta