Selecting multiple elements of an array by a list of indices

I have a list of indices, say `inds = [[1,2], [2,3],[4,4]]` that I want to use as indices into an array. For example, if

`A = reshape(1:16,4,4)`

then I would want to return the values `[5, 10, 16]`. I can, for example, use:

`[A[x[1],x[2]] for x in inds]`

but that seems very clumsy; I would want something more elegant, like `A[inds]` (which doesn’t work). What is the canonical Julia way of pulling a list of values from an array, using a list of indices to do so? And where can I find this in the documentation? It seems as though it would be a pretty standard sort of operation, but clearly I’ve either been looking in the wrong places, or misunderstanding what I’ve been reading… Anyway, thanks!

1 Like

A little bit less clumsy:

``````[A[x,y] for (x,y) in inds]
``````
4 Likes

Thank you - yes indeed that is more elegant. But can it be done without having to explicitly reference both indices in each pair?

Not sure, but I think no, because

`````` getindex(A, [2, 1])
``````

is already defined as returning `A[2]` and `A[1`] and not `A[1,2]`.

`A` is an `AbstractArray` in above case, so you could implement `getindex` for `AbstractMatrix`.
See

``````julia> methods(getindex)
``````

Thanks again - yes, I’ve been trying all sorts of combinations, but they return either a subarray, or an error. But I’ll check on `getindex`. Of course, given that I know the size of my array, I could create my indices as single values `i+n*(j-1)` for an n by n array. That would give me `inds = [5,10,16]` and then `A[inds]` works fine. In other words, using linear indexing instead of cartesian indexing.

Quick and Dirty and only for Int:

``````julia> import Base.getindex

julia> getindex(A::AbstractMatrix,i::AbstractArray{Int,1}) = A[i[1],i[2]]
getindex (generic function with 199 methods)

julia> A[[1,2]]
5
``````

A bit weird maybe but:

``````[A[i...] for i in inds]
``````
4 Likes

It can be done. `CartesianIndices` are your best friends when it comes to indexing.

``````julia> inds = [[1,2], [2,3],[4,4]];

julia> A = reshape(1:16,4,4);

julia> A[CartesianIndex.(Tuple.(inds))]
3-element Array{Int64,1}:
5
10
16
``````
5 Likes

Oh thank you! I had a vague inkling that `CartesianIndex` might be able to help, but I couldn’t see how to do it - so it’s all done with broadcasting! Very nice indeed, and again, many thanks.

1 Like

Thank you - clearly the triple dots hold some sort of magic of which I’m unaware. It does work though! (I’ve just discovered that this is in fact the superbly named splat operator.)