首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >阵列距离补码

阵列距离补码
EN

Stack Overflow用户
提问于 2017-02-22 03:33:28
回答 2查看 906关注 0票数 7

是否有一种方法可以覆盖[],使其在数组中具有范围的补充?

代码语言:javascript
复制
julia> a=[1:8...]
8-element Array{Int64,1}:
 1
 2
 3
 4
 5
 6
 7
 8

julia> a[-1] == a[2:8]
julia> a[-(1:3)] == a[4:8]
julia> a[-end] == a[1:7]
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-02-23 17:32:54

我以前还没有研究过索引的内部结构,但乍一看,下面的内容可能不会破坏太多:

代码语言:javascript
复制
immutable Not{T}
    idx::T
end    

if :to_indices in names(Base)
    # 0.6
    import Base: to_indices, uncolon, tail, _maybetail

    @inline to_indices(A, inds, I::Tuple{Not, Vararg{Any}}) =
       (setdiff(uncolon(inds, (:, tail(I)...)), I[1].idx), to_indices(A, _maybetail(inds), tail(I))...)       
else
    # 0.5
    import Base: getindex, _getindex

    not_index(a::AbstractArray, I, i::Int) = I
    not_index(a::AbstractArray, I::Not, i::Int) = setdiff(indices(a, i), I.idx)

    getindex(a::AbstractArray, I::Not) = getindex(a, setdiff(linearindices(a), I.idx))
    _getindex(::Base.LinearIndexing, a::AbstractArray, I::Vararg{Union{Real, AbstractArray, Colon, Not}}) = 
        Base._getindex(Base.linearindexing(a), a, (not_index(a, idx, i) for (i,idx) in enumerate(I))...)
end

例如:

代码语言:javascript
复制
julia> a = reshape(1:9, (3, 3))
3×3 Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}}:
1  4  7
2  5  8
3  6  9

julia> a[Not(2:8)]
2-element Array{Int64,1}:
1
9

julia> a[Not(1:2), :]
1×3 Array{Int64,2}:
3  6  9


julia> a[Not(end), end]
2-element Array{Int64,1}:
7
8

我不关心性能,也没有进行广泛的测试,所以事情当然可以改进。

编辑:

我用Matt .版本替换了0.6的代码,这个版本来自他在评论中链接的github评论。

由于他设计了0.6的数组索引实现,因此只需要扩展一个函数就可以获得getindexsetindexview的补充索引,例如,

代码语言:javascript
复制
julia> view(a, Not(2:8))
2-element SubArray{Int64,1,UnitRange{Int64},Tuple{Array{Int64,1}},false}:
1
9

# collect because ranges are immutable
julia> b = collect(a); b[Not(2), Not(2)] = 10; b
3×3 Array{Int64,2}:
10  4  10
 2  5   8
10  6  10  
票数 6
EN

Stack Overflow用户

发布于 2017-02-22 07:59:26

直接覆盖[](即getindex)容易破坏Base中许多与索引相关的内容,但是我们可以编写一个数组包装器来绕过它。我们只需要定义以下三种方法就可以通过特定的测试用例:

代码语言:javascript
复制
immutable ComplementVector{T} <: AbstractArray{T,1}
    data::Vector{T}
end
Base.size(A:: ComplementVector) = size(A.data)
Base.getindex(A:: ComplementVector, i::Integer) = i > 0 ? A.data[i] : A.data[setdiff(1:end, (-i))]
Base.getindex(A:: ComplementVector, I::StepRange) = all(x->x>0, I) ? A.data[I] : A.data[setdiff(1:end, -I)]

julia> a = ComplementVector([1:8...])

julia> a[-1] == a[2:8]
true

julia> a[-(1:3)] == a[4:8]
true

julia> a[-end] == a[1:7]
true

如果您想进一步扩展ComplementVector,请阅读有关Interfaces的文档。

更新:

为了安全起见,我们最好不要像王凤阳在评论中建议的那样扩展AbstractArray

代码语言:javascript
复制
immutable ComplementVector{T}
    data::Vector{T}
end
Base.endof(A::ComplementVector) = length(A.data)
Base.getindex(A::ComplementVector, i::Integer) = i > 0 ? A.data[i] : A.data[setdiff(1:end, (-i))]
Base.getindex(A::ComplementVector, I::OrdinalRange) = all(x->x>0, I) ? A.data[I] : A.data[setdiff(1:end, -I)]
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42382210

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档