TomTom
TomTom

Reputation: 2940

Collect iterator as 2D array

I'd like to create a 2D binary matrix, but Julia uses collect in an unexpected way and gives me a 3D matrix.

using Base.Iterators

collect(product(repeat([[0, 1]], 3)...))

Output

2×2×2 Array{Tuple{Int64,Int64,Int64},3}:
[:, :, 1] =
 (0, 0, 0)  (0, 1, 0)
 (1, 0, 0)  (1, 1, 0)

[:, :, 2] =
 (0, 0, 1)  (0, 1, 1)
 (1, 0, 1)  (1, 1, 1)

Iterating over the non-collected results however in the expected

for x in product(repeat([[0, 1]], 3)...)
    println(x)
end

Output

(0, 0, 0)
(1, 0, 0)
(0, 1, 0)
(1, 1, 0)
(0, 0, 1)
(1, 0, 1)
(0, 1, 1)
(1, 1, 1)

How do I collect the tuples of the iterator as a 2D matrix?

Upvotes: 0

Views: 188

Answers (1)

carstenbauer
carstenbauer

Reputation: 10157

Are you looking for something like this?

julia> X = product(repeat([[0, 1]], 3)...)
Base.Iterators.ProductIterator{Tuple{Array{Int64,1},Array{Int64,1},Array{Int64,1}}}(([0, 1], [0, 1], [0, 1]))

julia> X |> flatten |> collect |> x->reshape(x, (3,:))'
8×3 LinearAlgebra.Adjoint{Int64,Array{Int64,2}}:
 0  0  0
 1  0  0
 0  1  0
 1  1  0
 0  0  1
 1  0  1
 0  1  1
 1  1  1

Note that in your particular case the rows of the final matrix just correspond to binary counting from 0 to 2^3-1 = 7. You could simply construct the result directly:

julia> reduce(vcat, digits.(0:7, base=2, pad=3)')
8×3 Array{Int64,2}:
 0  0  0
 1  0  0
 0  1  0
 1  1  0
 0  0  1
 1  0  1
 0  1  1
 1  1  1

Upvotes: 1

Related Questions