Any shorter form of ``zip(1:2, cycle(3))''?


#1

Normally zip will stop if any component reaches end. e.g.,

julia> for (a,b) in zip(1:2,3)
       println("$a,$b")
       end
1,3

If I want it to align with the longest component (the shorter components just repeat), then have to write as

julia> for (a,b) in zip(1:2,cycle(3))
       println("$a,$b")
       end
1,3
2,3

My question is, is there any dedicated function for doing this latter task?


#2

You can always define your own, but zip(x, [Iterators.]cycle(y)) is pretty simple already.


#3

Okay, good to know that. It turns out to be a one-line thing :slight_smile:

julia> zip_align_first(a,b...) = zip(a, cycle.([b...])...)
zip_align_first (generic function with 1 method)

julia> collect(zip_align_first(1:6, 3, 4, [5,6], [7,8,9]))
6-element Array{Tuple{Int64,Int64,Int64,Int64,Int64},1}:
 (1,3,4,5,7)
 (2,3,4,6,8)
 (3,3,4,5,9)
 (4,3,4,6,7)
 (5,3,4,5,8)
 (6,3,4,6,9)

#4

You could also sort the arguments before zipping. That way, you do not need to pass the longest argument first:

julia> function zip_align(args...)
           sorted = sort([args...],by=x->-length(x))
           zip(sorted[1],cycle.(sorted[2:end])...)
       end
zip_align (generic function with 1 method)

julia> collect(zip_align([1,2,3],[4,5],[6,7,8,9,10]))
5-element Array{Tuple{Int64,Int64,Int64},1}:
 (6,1,4)
 (7,2,5)
 (8,3,4)
 (9,1,5)
 (10,2,4)