Collect (flat) iterator as an Array

Is there a default generic way I can collect an iterator itr that HasLength into an Array of given (compatible) dims?

Eg collect

itr = (i for i in 1:6)

into a 2x3 Matrix.

Just to clarify, it is easy to write a wrapper that provides the given size. I am asking if there is a package with this functionality, or if I can somehow do it in base.

1 Like

And just to clarify, I am not looking for reshape(collect(itr), (2,3)), but a generic mechanism that endows an iterator with a given shape.

Could do something like

struct ShapedIterator{I, N}
    itr::I
    shape::NTuple{N, Int}
end 
shaped(itr, shape...) = let l = prod(shape)
    l == length(itr) || error("something informative")
    ShapedIterator(itr, shape)
end

Base.IteratorSize(s::ShapedIterator{<:Any, N}) where {N} = Base.HasShape{N}()
Base.IteratorEltype(s::ShapedIterator) = Base.IteratorEltype(s.itr)
Base.eltype(s::ShapedIterator) = eltype(s.itr)
Base.size(s::ShapedIterator) = s.shape
Base.iterate(s::ShapedIterator, args...) = iterate(s.itr, args...)
julia> collect(shaped((i for i in 1:6), 2, 3))
2×3 Matrix{Int64}:
 1  3  5
 2  4  6

Edit: sorry I missed that you explicitly said you don’t want to write a wrapper and want to use a package, sorry for the noise.

Maybe this function could be added to IterTools.jl as a PR?

2 Likes

no worries, I should have been more explicit.

yes indeed. but I thought I would ask first if a package already has it.

1 Like