I want to slice an array ignoring any out-of-bounds indices. Is there a preferred way to do this?

My solution

```
safeslice(a, ixs) = a[filter(i -> checkbounds(Bool, a, i), ixs)]
julia> safeslice([10,20,30], -4:2)
2-element Vector{Int64}:
10
20
```

I want to slice an array ignoring any out-of-bounds indices. Is there a preferred way to do this?

My solution

```
safeslice(a, ixs) = a[filter(i -> checkbounds(Bool, a, i), ixs)]
julia> safeslice([10,20,30], -4:2)
2-element Vector{Int64}:
10
20
```

You should consider something using `intersect`

on the `CartesianIndices`

```
julia> a = zeros(3,4,5);
julia> a[intersect(CartesianIndices(a),CartesianIndices((3:5,3:5,3:5)))]
1×2×3 Array{Float64, 3}:
[:, :, 1] =
0.0 0.0
[:, :, 2] =
0.0 0.0
[:, :, 3] =
0.0 0.0
```

This will figure out the valid indices up front, so won’t have to check each index individually. In this way, it should be much more efficient (if that matters to your case). It should also make it safe to use with `@inbounds`

, which may be necessary to get the full efficiency out of it.

You can also look into the `get`

function, if you want some other value returned on the invalid indices (but that does not appear to be your case here).

2 Likes

```
(partialgetindices(a, ixs::T) where T <: AbstractArray{CartesianIndex{S}} where S) =
a[intersect(CartesianIndices(a), ixs)]
julia> partialgetindices([10,20,30], CartesianIndex.([0,1,2]))
2-element Vector{Int64}:
10
20
```

Here’s a version I threw together, based on intersecting the `axes`

rather than `CartesianIndices`

but otherwise very similar. By using `to_indices`

, this one supports `:`

and `::Int`

indices as well. It doesn’t drop `::Int`

slices like normal `getindex`

does, since it needs to be able to drop if the value is out of range. You might find it slightly more ergonomic.

```
julia> partialgetindices(a::AbstractArray{<:Any,N}, ixs::Vararg{Any,N}) where N = a[intersect.(axes(a), to_indices(a, ixs))...]
partialgetindices (generic function with 1 method)
julia> a = zeros(3,4,5);
julia> partialgetindices(a,-10:2,:,1)
2×4×1 Array{Float64, 3}:
[:, :, 1] =
0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0
```

2 Likes