Better way to do ```getindex.```

I often have a need to index a list of lists at a single index and use, e.g.:

getindex.( list_of_lists, 1 )

I would love to instead write list_of_lists.[1] but this seems to be invalid syntax. Is there some other way of doing getindex.?

1 Like

You can do first.(x), but I guess that’s similar to the getindex solution. Using .[1] won’t work.

2 Likes

In the future: nth https://github.com/JuliaLang/julia/pull/56580

3 Likes

I think it would make total sense for A.[B] to lower to getindex.(A, B), but this proposal has proven a bit controversial in the past

1 Like

In particular, see Broadcast Array Indexing · Issue #19169 · JuliaLang/julia · GitHub and What to do about nonscalar indexing? · Issue #30845 · JuliaLang/julia · GitHub

1 Like

Thank you. I now see that this doesn’t make sense. The “.” operator maps across the arguments which are on the right and not the function which is on the left. q, an APL-derived language used in much of finance, has two different operators for mapping leftwards and rightwards (/ and \ if I rememeber correctly). I guess something like that would be too much to hope for.

Without defining new syntax, there are many hacks you can try out. I don’t promise these won’t break things… probably a bad idea except for messing around! The last of these is what I wish for most often.

julia> (x::Array)(i...) = x[i...]  # make arrays callable?

julia> [[1,2,3], [3,5,6]].(2)  # broadcast that call
3-element Vector{Int64}:
 3
 5
 6

julia> [[1,2,3], [3,5,6]].([1 1 2])
1Ă—3 Matrix{Vector{Int64}}:
 [1, 2, 3]  [1, 2, 3]  [3, 5, 6]

julia> Base.:(~)(x::Array, i::Int) = x[i]  # infix operator, but only has 1-arg methods in Base

julia> [[1,2,3], [3,5,6]].~2
2-element Vector{Int64}:
 2
 5

julia> Base.getproperty(x::Array, i::Integer) = getindex.(x, i)

julia> [[1,2,3], [3,5,6]].:2
2-element Vector{Int64}:
 2
 5

julia> [(1,2), (3,4)].:1
2-element Vector{Int64}:
 1
 3

julia> function Base.getproperty(x::Array, s::Symbol)
         s === :ref && return getfield(x, :ref)
         s === :size && return getfield(x, :ref)
         getproperty.(x, s)
       end

julia> [(a=1,b=2), (a=3,b=4)].a
2-element Vector{Int64}:
 1
 3
4 Likes

Both A.:2 and A.a work for StructArrays with this exact semantic :slight_smile: They are only applicable when all elements have the same static length though.

1 Like