I am looking for the recommended way to “drop” the shape property of an iterator. Eg for
itr = Iterators.product(1:5, 1:2)
I want itr_flat
such that
collect(itr_flat) == vec(collect(itr))
without, of course, collecting it first.
It is relatively straightforward to implement a wrapper that does this, just curious if it is defined anywhere, or if there is a clever way to do it.
julia> itr_flat = Iterators.take(itr, length(itr))
Base.Iterators.Take{Base.Iterators.ProductIterator{Tuple{UnitRange{Int64}, UnitRange{Int64}}}}(Base.Iterators.ProductIterator{Tuple{UnitRange{Int64}, UnitRange{Int64}}}((1:5, 1:2)), 10)
julia> collect(itr_flat)
10-element Vector{Tuple{Int64, Int64}}:
(1, 1)
(2, 1)
(3, 1)
(4, 1)
(5, 1)
(1, 2)
(2, 2)
(3, 2)
(4, 2)
(5, 2)
works on iterators of predetermined length, but feels a bit hackish.
On the other hand, the shape matters only when collected, right? But then you might as well do reshape(x,:)
on the result.
1 Like
What about this:
itr_flat = Iterators.flatten((Iterators.product(1:5, 1:2),))
collect(itr_flat)
10-element Vector{Tuple{Int64, Int64}}:
(1, 1)
(2, 1)
(3, 1)
(4, 1)
(5, 1)
(1, 2)
(2, 2)
(3, 2)
(4, 2)
(5, 2)
3 Likes
Thanks for both answers. They are nice workarounds, but I think that something like an Iterators.vec
would convey semantics better. I will make a PR.
EDIT Silly me, there is IterTools.ivec
.
2 Likes
IterTools
… Of course Good to know!
Another hack is to use comprehension with if true
clause
itr = Iterators.product(1:5, 1:2)
itr_flat = (x for x in itr if true)
collect(itr_flat) == vec(collect(itr))
1 Like