Eachindex for individual axes of multidimensional arrays?

gjm
Wed, 18 May 2022 14:26:24 +0000
Internals & Design

Because arrays’ indices don’t generally start from 1, best practice is to avoid anything like “for i in 1:size()” and instead use eachindex. But for multidimensional arrays, eachindex iterates over all elements of the array, and sometimes you want to iterate only over some subset of its dimensions. (For instance: if you have a sequence of points in the plane, represented by a 2-dimensional array. Iterating over all the points means iterating over just one of the dimensions.)

If I understand correctly, the approved way to do this is something like

for i in firstindex(A,2):lastindex(A,2)
    x,y = A(1,i),A(2,i)
    # ... do something with x,y ...
end

but this is a bit cumbersome. (And when something is cumbersome, people will tend to do something less cumbersome instead even if it isn’t quite right. I bet there are a lot of loops of this sort that go from 1 to size(A,whatever). And all those loops are wrong if it is possible for A to be an OffsetArray.)

I suggest that eachindex should take an optional second argument, a dimension number; obviously this should only succeed when the first argument is an AbstractArray rather than, say, a dictionary. So the loop above would become

for i in eachindex(A,2)
    x,y = A(1,i),A(2,i)
    # ... do something with x,y ...
end

eachindex can already take multiple arguments; they are all expected to be AbstractArrays of the same size and eachindex will return an indices object that works with them all. My proposal would give another meaning to calling eachindex with multiple arguments. Unless I am missing something there is no case in which it would give a new meaning to anything that was not previously illegal.

8 posts - 5 participants