Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to iterate over two arrays in parallel

Tags:

julia

I have two arrays that I want to iterate over at the same time.

I'm using this:

julia> xs = [1,2,3];

julia> ys = [4,5,6];

julia> for i in 1:length(xs)
           x = xs[i]
           y = ys[i]
           @show x, y
       end
(x, y) = (1, 4)
(x, y) = (2, 5)
(x, y) = (3, 6)

Is there a better way to iterate over multiple arrays in Julia?

like image 542
David Varela Avatar asked Jan 12 '20 05:01

David Varela


Video Answer


2 Answers

Use zip along with tuple destructuring:

julia> xs = [1,2,3];

julia> ys = [4,5,6];

julia> for (x, y) in zip(xs, ys)
           @show x, y
       end
(x, y) = (1, 4)
(x, y) = (2, 5)
(x, y) = (3, 6)

zip will stop iteration at the shortest array:

julia> for (x, y) in zip([1,2], [0,0,0])
           @show x, y
       end
(x, y) = (1, 0)
(x, y) = (2, 0)

This pattern can be generalized to an arbitrary number of lists:

julia> for (x, y, z) in zip([1,2], [3,4], [5,6])
           @show x, y, z
       end
(x, y, z) = (1, 3, 5)
(x, y, z) = (2, 4, 6)
like image 73
David Varela Avatar answered Nov 22 '22 21:11

David Varela


One possibility consists in using the eachindex function: if it is given multiple Array-like arguments, it will return a iterable set of indices suitable to iterate on all arguments at once.

This is useful in particular in the following situations:

  • when you need to use the index itself (for example because you don't only need to access the elements of the collections, but also set some of them), or
  • when you want to check that both arrays indeed have the same number of elements (this might or might not be a desired property depending on your use case).


Example 1: using the index itself to fill the first array with values coming from the second

julia> x = [1,2,3];

julia> y = [4,5,6];
julia> @inbounds for i in eachindex(x, y)
           x[i] = 2*y[i]
       end
julia> x
3-element Array{Int64,1}:
  8
 10
 12


Example 2: check that the arrays have the same range

julia> x = [1,2];
julia> y = [4,5,6];

julia> @inbounds for i in eachindex(x, y)
           x[i] = 2*y[i]
       end
ERROR: DimensionMismatch("all inputs to eachindex must have the same indices, got [1, 2] and [1, 2, 3]")


Example 3: note that eachindex generalizes well for multi-dimensional arrays too.

julia> x = zeros(2, 3);
julia> y = ones(2, 3);

julia> @inbounds for i in eachindex(x, y)
           x[i] = 2*y[i]
       end
julia> x
2×3 Array{Float64,2}:
 2.0  2.0  2.0
 2.0  2.0  2.0
like image 43
François Févotte Avatar answered Nov 22 '22 21:11

François Févotte