Indexing Julia在访问数组时重新定义索引
我有一个实现数组接口的结构。我想在访问它时重新定义索引。到目前为止,我是在我的类型的Indexing Julia在访问数组时重新定义索引,indexing,julia,Indexing,Julia,我有一个实现数组接口的结构。我想在访问它时重新定义索引。到目前为止,我是在我的类型的Base.getindex函数中完成的,但是我在文档中看到了Base.to\u index函数,不知道它们是如何协同工作的 可以使用:(Colon)、UnitRange、StepRange、OneTo、Int或Int数组访问数组元素,那么我应该在哪里重新定义索引而不必管理所有这些情况呢?在摘要中很难谈论这一点。下面是一个具体的例子: struct ReversedRowMajor{T,A} <: Abstr
Base.getindex
函数中完成的,但是我在文档中看到了Base.to\u index
函数,不知道它们是如何协同工作的
可以使用
:
(Colon
)、UnitRange
、StepRange
、OneTo
、Int
或Int数组
访问数组元素,那么我应该在哪里重新定义索引而不必管理所有这些情况呢?在摘要中很难谈论这一点。下面是一个具体的例子:
struct ReversedRowMajor{T,A} <: AbstractMatrix{T}
data::A
end
ReversedRowMajor(data::AbstractMatrix{T}) where {T} = ReversedRowMajor{T, typeof(data)}(data)
Base.size(R::ReversedRowMajor) = reverse(size(R.data))
Base.getindex(R::ReversedRowMajor, i::Int, j::Int) = R.data[end-j+1, end-i+1]
请注意,我们没有使用排列和计算的索引重新索引到R
——新的索引直接提供给父数组R.data
另一方面,to_index
,将以前不受支持的索引类型简单转换为Int
或Int
数组,然后使用这些转换后的索引将索引重新转换为R
本身。注意调用R[Int8(1),Int8(1)]
时会发生什么:
这并没有调用您定义的任何方法-还没有。您没有定义如何获取索引(::ReversedRowMajor,::Int8,::Int8)
。朱莉娅正在为你处理这个案子。它使用to_index
将Int8
转换为Int
,然后再次调用R[1,1]
。现在它击中了您定义的方法
简言之:此数组有一个简单的
getindex
方法,该方法使用Int
索引重新计算对父数组的访问<另一方面,如果您没有定义匹配方法,则code>to_index会将所有其他类型的索引转换为支持的索引,并将其转换为相同的数组。您无法使用到_index
进行所需的转换,因为不清楚R[1,2]
是使用转换前的索引还是转换后的索引。您所说的“重定义”是什么意思?你能举一个你想发生什么的例子吗?例如,排列索引并对它们应用转换(i=f(i)
)你是对的,在这个例子中谈论它更容易。在这个例子中(离我想做的不远),如果调用R[:,:],就会出现性能问题,因为eachindex将以笛卡尔指数的非最佳顺序迭代。有没有办法告诉Julia这个数组的最佳迭代顺序是什么?问题开始了:
julia> R = ReversedRowMajor([1 2; 3 4; 5 6])
2×3 ReversedRowMajor{Int64,Array{Int64,2}}:
6 4 2
5 3 1
julia> R[:, isodd.(R[1,:].÷2)]
2×2 Array{Int64,2}:
6 2
5 1
julia> @view R[[1,4,5]]
3-element view(reshape(::ReversedRowMajor{Int64,Array{Int64,2}}, 6), [1, 4, 5]) with eltype Int64:
6
3
2
julia> @which R[Int8(1),Int8(1)]
getindex(A::AbstractArray, I...) in Base at abstractarray.jl:925