Joshuah Heath
Joshuah Heath

Reputation: 673

Alternative to nested for-loop in Julia

Given arbitrary integers a and b, I want to create a list of all different pairs within Z_a^b \times Z_a^b. For example, taking a=3 and b=2, I want to have an array

[[[0,0],[0,0]],[[0,0],[0,1]],[[0,0],[0,2]],...,[[2,2],[2,1]],[[2,2],[2,2]]] 

I want to do this within Julia. However, I do not know how to do this easily for arbitrary values of b (even for fixed b, the only way I can think to do this would be nested for loops). Is there a quick way of implementing this?

Upvotes: 3

Views: 334

Answers (1)

Bogumił Kamiński
Bogumił Kamiński

Reputation: 69869

Is this what you want?

julia> Z(a, b) = Iterators.product([0:a-1 for _ in 1:b]...)
Z (generic function with 1 method)

julia> collect(Iterators.product(Z(3,2), Z(3,2))) |> vec
81-element Vector{Tuple{Tuple{Int64, Int64}, Tuple{Int64, Int64}}}:
 ((0, 0), (0, 0))
 ((1, 0), (0, 0))
 ((2, 0), (0, 0))
 ((0, 1), (0, 0))
 ((1, 1), (0, 0))
 ((2, 1), (0, 0))
 ((0, 2), (0, 0))
 ((1, 2), (0, 0))
 ((2, 2), (0, 0))
 ((0, 0), (1, 0))
 ⋮
 ((0, 0), (2, 2))
 ((1, 0), (2, 2))
 ((2, 0), (2, 2))
 ((0, 1), (2, 2))
 ((1, 1), (2, 2))
 ((2, 1), (2, 2))
 ((0, 2), (2, 2))
 ((1, 2), (2, 2))
 ((2, 2), (2, 2))

julia> collect(Iterators.product(Z(4,3), Z(4,3))) |> vec
4096-element Vector{Tuple{Tuple{Int64, Int64, Int64}, Tuple{Int64, Int64, Int64}}}:
 ((0, 0, 0), (0, 0, 0))
 ((1, 0, 0), (0, 0, 0))
 ((2, 0, 0), (0, 0, 0))
 ((3, 0, 0), (0, 0, 0))
 ((0, 1, 0), (0, 0, 0))
 ((1, 1, 0), (0, 0, 0))
 ((2, 1, 0), (0, 0, 0))
 ((3, 1, 0), (0, 0, 0))
 ((0, 2, 0), (0, 0, 0))
 ((1, 2, 0), (0, 0, 0))
 ⋮
 ((3, 1, 3), (3, 3, 3))
 ((0, 2, 3), (3, 3, 3))
 ((1, 2, 3), (3, 3, 3))
 ((2, 2, 3), (3, 3, 3))
 ((3, 2, 3), (3, 3, 3))
 ((0, 3, 3), (3, 3, 3))
 ((1, 3, 3), (3, 3, 3))
 ((2, 3, 3), (3, 3, 3))
 ((3, 3, 3), (3, 3, 3))

Note that I collect it to make the result visible. Normally, as the result set can be very large it is better to stay with lazy Iterators.product and just iterate it.

Upvotes: 4

Related Questions