6.20.2.2 Combining (zipping) iterators

The collections.zip2(K,V) templated module provides a way of iterating over two containers of potentially different types in a single for loop, for example,

from collections.zip2(K=int, V=string) access zip, operator cast;
int[] x = {0, 1, 2, 3};
string[] y = {'0', '1', '2', '3'};
for (var ab : zip(x, y)) {
  assert(string(ab.k) == ab.v);
}

where

Iterable_Pair_K_V zip(Iterable_K a, Iterable_V b,
                      Pair_K_V keyword default=null)

returns an iterable that produces pairs of elements from a and b. If default is not provided, the iterable stops when either a or b runs out of elements. If default is provided, the returned iterable will be the length of the longer of a and b, and the default value will be used for any missing elements.

Additionally, the module exposes the following types and all their autounravels:

typefrom
Pair_K_Vcollections.genericpair(K,V)
Iterable_Kcollections.iter(T=K)
Iterable_Vcollections.iter(T=V)
Iterable_Pair_K_Vcollections.iter(T=Pair_K_V)
Iter_Kcollections.iter(T=K)
Iter_Vcollections.iter(T=V)
Iter_Pair_K_Vcollections.iter(T=Pair_K_V)

The collections.zip(T) templated module provides a way to iterate over multiple containers in a single for loop. It is similar to collections.zip2(K,V), but condenses the iterables into an iterable over arrays rather than over pairs. This requires that all the iterables be over the same type (for example, all string iterators or all integer iterators):

from collections.zip(T=int) access zip;
int[] x = {0, 1, 2, 3};
int[] y = {0, 1, 2};
int[] z = {0, 1, 2, 3, 4};
for (int[] abc : zip(default=-1, x, y, z)) {
  write(string(abc[0]) + '\t' + string(abc[1]) + '\t' + string(abc[2]));
}

which outputs

0       0       0
1       1       1
2       2       2
3       -1      3
-1      -1      4

The collections.zip(T) module exposes the types

typefrom
Iterable_array_Tcollections.iter(T=T[])
Iter_array_Tcollections.iter(T=T[])
Iterable_Tcollections.iter(T)
Iter_Tcollections.iter(T)

and defines the following functions (all called zip):

Iterable_array_T zip(...Iterable_T[] iterables)

zips together one or more iterables of Ts. If a is an item from the result, then a[0] is from the first iterable, a[1] is from the second iterable, and so on. If the iterables are not all the same length, the result will be the length of the shortest iterable.

Iterable_array_T zip(T keyword default ...Iterable_T[] iterables)

zips together one or more iterables of Ts. The result will be the length of the longest iterable, with the default value filling in any missing elements.

T[][] zip(...T[][] arrays)

zips together one or more arrays. If the arrays are not all the same length, the result will be the length of the shortest array.

T[][] zip(T keyword default ...T[][] arrays)

zips together one or more arrays. The result will be the length of the longest array, with the default value filling in any missing elements. This is basically equivalent to applying transpose and then replacing any uninitialized elements with the default value.