Convert iterator (of tuples) to vector

I have an iterator, and I wish to convert it into an array. Normally, I could just do:

vec = [i for i in iter]

or

vec = map(i -> i, iter]

but now my iterator happens to contain tuples (of numbers). It is generated as:

iter = Iterators.product(1:10,1:10,1:10)

and if I now do either one of

vec = [i for i in iter]
vec = map(i -> i, iter]

I get a 3d array, which is awkward, since I want a vector. The only way I have found is to do:

vec = [];
foreach(i -> push!(vec,i), iter)

but this feels a little bit more convoluted than what should be possible. It feels like I am missing something here, which I don’t understand, which is why the first two approaches doesn’t work.

You can use Iterators.flatten and then collect the result:

julia> iter = Iterators.product(1:10,1:10,1:10)
Base.Iterators.ProductIterator{Tuple{UnitRange{Int64}, UnitRange{Int64}, UnitRange{Int64}}}((1:10, 1:10, 1:10))

julia> collect(Iterators.flatten(iter))
3000-element Vector{Int64}:
  1
  1
  ⋮
 10
 10
1 Like

Also note that the reason why collecting that iterator returns an array of size (10, 10, 10) is, that the Iterator returned by Iterators.product defines size():

julia> size(iter)
(10, 10, 10)

See this part of the documentation for how the iterator interface works.

In other words: If size() were undefined (or would return 1000) for that particular iterator, the result would be what you had expected.

2 Likes

Thanks, that helps explain what is going on. Is there a way to still get it as tuples though? E.g.

Iterators.product(1:10,1:10,1:10)

returns

1
1
1

but I want still the tuple values:

(1,1,1)
(2,1,1)
(3,1,1)
...

Okay, misunderstood what you wanted. Then you can use vec:

julia> iter = Iterators.product(1:10,1:10,1:10);

julia> vec(collect(iter))
1000-element Vector{Tuple{Int64, Int64, Int64}}:
 (1, 1, 1)
 (2, 1, 1)
 ⋮
 (9, 10, 10)
 (10, 10, 10)
3 Likes

Thanks! :slight_smile: