Is it possible to have the last iterator change the fastest in Iterator.product?

In Julia’s Iterators.product, the first iterator changes the fastest. Is there an easy way to get elements in an order, so that the last iterator changes the fastest? For example with three sequences, I obtain:

res = Iterators.product([:A, :B, :C], [:X, :Y], [1,2]) |> collect
3×2×2 Array{Tuple{Symbol, Symbol, Int64}, 3}:
[:, :, 1] =
 (:A, :X, 1)  (:A, :Y, 1)
 (:B, :X, 1)  (:B, :Y, 1)
 (:C, :X, 1)  (:C, :Y, 1)

[:, :, 2] =
 (:A, :X, 2)  (:A, :Y, 2)
 (:B, :X, 2)  (:B, :Y, 2)
 (:C, :X, 2)  (:C, :Y, 2)

If I get elements using res[:] I obtain:

julia> res[:]
12-element Vector{Tuple{Symbol, Symbol, Int64}}:
 (:A, :X, 1)
 (:B, :X, 1)
 (:C, :X, 1)
 (:A, :Y, 1)
 (:B, :Y, 1)
 (:C, :Y, 1)
 (:A, :X, 2)
 (:B, :X, 2)
 (:C, :X, 2)
 (:A, :Y, 2)
 (:B, :Y, 2)
 (:C, :Y, 2)

Instead, I want:

(:A, :X, 1)
 (:A, :X, 2)
 (:A, :Y, 1)
 (:A, :Y, 2)
 (:B, :X, 1)
 (:B, :X, 2)
 (:B, :Y, 2)
 (:B, :Y, 2)
(:C, :X, 1)
 (:C, :X, 2)
 (:C, :Y, 2)
 (:C, :Y, 2)
 

What is the easiest way to get that from the res variable? Thank you!

May I suggest you use different elements in the three iterators for your example? I think that would make it clearer

1 Like
julia> res = Iterators.map(reverse, Iterators.product([:C, :D], [:C, :D], [:C, :D])) |> collect |> vec
8-element Vector{Tuple{Symbol, Symbol, Symbol}}:
 (:C, :C, :C)
 (:C, :C, :D)
 (:C, :D, :C)
 (:C, :D, :D)
 (:D, :C, :C)
 (:D, :C, :D)
 (:D, :D, :C)
 (:D, :D, :D)
4 Likes

One way to do that is to use reverse:

reverse.(res)

But you’ll probably want to first reverse the order of the arguments to product, too.

Thank you @Elrod and @lostella. This works for the example I had given earlier. On lostella’s suggestion I changed the example to have different elements. This “reverse” solution does not work for the modified example. Is there a solution that works for this modified example?

Actually using reverse along with reversing the order of arguments to the Iterators.product (as lostella suggested) works well.

Thank you.

1 Like