I wonder if there is an API for testing if something returned by to_indices
is a “scalar” index (ie one that would drop dimensions). I could not find anything, and I think it would be useful to have, and thought I would ask here before making a PR before the 1.2 feature freeze.
One can of course rely on the documentation and note that currently “scalar” indexes are Int
or CartesianIndex
. But this may change in the future, just like CartesianIndex
was introduced.
The proposal is something trivial like
is_scalar_index(::Integer) = true
is_scalar_index(::CartesianIndex) = true
is_scalar_index(_) = false
An MWE for some context is
"""
Wrapper for vectors, supports subsetting via [].
"""
struct Foo
a # both are <: AbtractVector, but here omit
b # type parameters to simplify example
function Foo(a, b)
@assert axes(a) == axes(b)
new(a, b)
end
end
Base.firstindex(f::Foo) = firstindex(f.a)
Base.lastindex(f::Foo) = lastindex(f.a)
function Base.getindex(f::Foo, i)
ι = first(to_indices(f.a, (i, )))
if ι isa Union{Integer, CartesianIndex} # this would be more robust
error("subset using non-scalar indexes")
else
Foo(f.a[ι], f.b[ι])
end
end
with
julia> f = Foo(1:5, ones(5))
Foo(1:5, [1.0, 1.0, 1.0, 1.0, 1.0])
julia> f[2:3]
Foo(2:3, [1.0, 1.0])
julia> f[2]
ERROR: subset using non-scalar indexes
Stacktrace:
[1] error(::String) at ./error.jl:33
[2] getindex(::Foo, ::Int64) at ./REPL[19]:4
[3] top-level scope at REPL[27]:1