Get row slice both to Vector and Matrix

Is there an official way that can get row slice both to Vector and Matrix. It would works like this:

vec_data = [1,2,3,4]
mat_data = [[1,2,3,4] [2,3,4,5]]

row_index = RowIndex(1:3)

vec_data[row_index]

Vector{Int}
1
2
3

mat_data[row_index]

Matrix{Int}
1 2
2 3
3 4

julia> struct RowIndex
           range::AbstractUnitRange
       end

julia> row_index = RowIndex(1:3)
RowIndex(1:3)

julia> function Base.getindex(a::AbstractArray{T,N}, row_index::RowIndex) where {T,N}
           ind = ntuple(N) do i
               i == 1 ? row_index.range : Colon()
           end
           getindex(a, ind...)
       end

julia> vec_data[row_index]
3-element Vector{Int64}:
 1
 2
 3

julia> mat_data[row_index]
3×2 Matrix{Int64}:
 1  2
 2  3
 3  4
1 Like

The answer above works if you want a special object for this operation. However, this can be done just using Julia’s native indexing rules with no special objects:

vec_data = [1,2,3,4]
mat_data = [[1,2,3,4] [2,3,4,5]]
rows = 1:3
vec_data[rows,:]
mat_data[rows,:]
1 Like

Thanks for your help. The RowIndex works fine. But is there an official way in julia which is similar to the RowIndex ?

This does not work, It return a Matrix rather than Vector. It is the mechanism that makes me headeach

Does the remainder of your code not work for a Matrix in that position? There’s a good chance it will. If not, then you’ll need to write things differently or use the suggested RowIndex object from the earlier answer.

Akin to the RowIndex object above, but without defining or building it specifically, you could use this function:

getrows(x::AbstractVector,rows) = x[rows]
getrows(x::AbstractMatrix,rows) = x[rows,:]
# can write for higher dimensional arrays if needed
# or can write a single definition that works for any number of dimensions, which looks much like the `getindex` function for `RowIndex`  defined above
1 Like

In the context, the code work for Vetor or Matrix.

Define a function is intuitive, but I would thought thers is a more elegant way like CartesianIndex or some way else that is created to do this.

In terms of already available functions, there is also selectdim(v, 1, idxs), which will select entries of the array where the first index varies within idxs. In your example,

julia> selectdim(vec_data, 1, 1:3)
3-element view(::Vector{Int64}, 1:3) with eltype Int64:
 1
 2
 3

julia> selectdim(mat_data, 1, 1:3)
3×2 view(::Matrix{Int64}, 1:3, :) with eltype Int64:
 1  2
 2  3
 3  4

This returns a view of the original array rather than copying the data, not sure which is best for your use case (you can always call copy on the output to get a copy of the data).

3 Likes

Thanks for your help. This function selectdim do the exactly same thing as RowIndex.