我在 Julia 中有一些特殊定义的数组,你可以认为它们只是许多数组的组合。例如:
type CompositeArray{T}
x::Vector{T}
y::Vector{T}
end
有一个索引方案
getindex(c::CompositeArray,i::Int) = i <= length(c) ? c.x[i] : c.y[i-length(c.x)]
我确实有一个警告:更高的索引方案只会转到 x
本身:
getindex(c::CompositeArray,i::Int...) = c.x[i...]
现在,通过这些的迭代器可以很容易地制成 x
上的迭代器链,然后是 y
上的迭代器链。这使得迭代值几乎没有额外成本。但是,是否可以对 setindex!
的迭代执行类似的操作?
我正在考虑对 CartesianIndex{2}
进行单独调度,仅用于索引 x
与 y
和索引,并构建一个eachindex
迭代器,类似于 CatViews.jl does .但是,我不确定它将如何与 i...
调度交互,或者它在这种情况下是否有用。
此外,如果构建在eachindex
上,广播会自动使用这种快速迭代方案吗?
编辑:
length(c::CompositeArray) = length(c.x) + length(c.y)
在实际情况下,x
可以是任何 AbstractArray
(因此具有线性索引),但由于仅使用线性索引(除了那个用户-面向 getindex
函数),问题实际上归结为找出如何使用 x
一个 Vector 来做到这一点。
最佳答案
让 X[CartesianIndex(2,1)]
与 X[2,1]
有不同的含义肯定不会有好结果。而且我预计 X[100,1]
可能意味着与 X[100]
不同的东西,或者如果 length(X) !=产品(尺寸(X))
。您可以自由地打破规则,但是当 Base 和其他包中的函数希望您遵守它们时,您不应该感到惊讶。
执行此操作的安全方法是使 eachindex(::CompositeArray)
返回一个自定义迭代器,覆盖您完全控制的对象。如果该数据结构有帮助,也许只是抛出一个包装器并将方法转发给 CartesianRange
和 CartesianIndex{2}
。然后,当您获得这些自定义索引类型之一时,您就会知道 SplitIndex(CartesianIndex(1,2))
确实打算引用第二个数组中的第一个元素。
关于arrays - 迭代 `setindex!`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42227434/