Using CartesianRange, flattening before collect

question

#1

I need to iterate through all possible indices of an array for a unit test, without constructing the array, ie just from the indices. Is

  1. constructing a CartesianRange,
  2. then iterating through it and extracting the I slot

the way to do this? I am asking because it is not documented, so I am not sure if this is an interface I should rely on being reasonably stable. Example:

function simulate_index_weights(_size...)
    vec(collect(c.I => rand() for c in CartesianRange(_size)))
end

simulate_index_weights(2,3,4)

Also, is there a more elegant way of discarding shape information from a generator before collecting, so that I would not have to call vec?


#2

Very stable and very much the way forward. A docstring PR would be most appreciated!

I wouldn’t say there’s any particular reason to pass back c.I, just return c. It gives you faster indexing because you don’t have to splat a tuple.

I think calling vec is your best best. What seems inelegant about that?


#3

Thanks for the help.

Perhaps I should rephrase: is there a way to take a generator with a shape, and convert it to a “flat” generator, without collecting?

Just curious.


#4

Some options are

copy!(similar(Array{eltype(C)}, length(C)), C)
copy!(Vector{eltype(C)}(length(C)), C)
Vector{eltype(C)}(length(C)) .= C

#5

Perhaps something like this?

simulate_index_weights(_size...) = (c.I => rand() for c in CartesianRange(_size))
for x in simulate_index_weights(2,3,4)
    println(x)
end