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.
Mason
January 10, 2024, 12:45pm
3
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
Mason:
sorry I missed
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