zip
is a useful function, but it can be frustrating because it does not behave like a “real” array even when its underlying iterables are. For instance, I would expect that if all underlying iterables passed to zip
support getindex
, then so would the Zip
, by calling it in turn on each underlying iterable and then collecting the results into a tuple. But this is not the case:
julia> a = 1:10
1:10
julia> a[4]
4
julia> zip(a, a)[4] # I'd expect this to be (a[4], a[4]) == (4, 4)
ERROR: MethodError: no method matching getindex(::Base.Iterators.Zip{Tuple{UnitRange{Int64}, UnitRange{Int64}}}, ::Int64)
This makes composing functionality with Zip
s much harder than it could be. Similar difficulties include the fact that eachindex
, keys
, findall
, etc. do not work on Zip
s. Perhaps a new function/type, indexed_zip
/IndexedZip
, that expects the underlying iterables to support getindex
and forwards related functions to the underlying iterables before collecting them into a tuple? The implementation would look like this:
Base.getindex(z::Iterators.IndexedZip, i) = (it -> getindex(it, i)).(z.is)