How to iterate over everything except the last AbstractArray index

In Julia, the recommended way to iterate over all indexes AbstractArrayis to use eachindex, for example,

for i in eachindex(a)
    do_something(a[i], i)
end

In contrast 1:length(a), it eachindex(a)supports arrays with non-traditional indexing, i.e. indexes do not start with 1. In addition, it is more efficient for arrays with slow linear indexing.

If I want to skip the first index, I can use Iterators.drop(eachindex(a), 1)(is there a better way?), But how to skip the last in general?

+4
source share
3 answers

"" . : , . Base builtins :

front(itr, n=1) = Iterators.take(itr, length(itr)-n)

length, - , eachindex.


, length. . Julia 0.6, :

struct Front{T}
    itr::T
end
# Basic iterator definition
function Base.start(f::Front)
    s = start(f.itr)
    done(f.itr, s) && throw(ArgumentError("cannot take the front of an empty iterator"))
    return next(f.itr, s)
end
function Base.next(f::Front, state)
    val, s = state
    return val, next(f.itr, s)
end
Base.done(f::Front, state) = done(f.itr, state[2])

# Inherit traits as appropriate
Base.iteratorsize(::Type{Front{T}}) where {T} = _dropshape(Base.iteratorsize(T))
_dropshape(x) = x
_dropshape(::Base.HasShape) = Base.HasLength()
Base.iteratoreltype(::Type{Front{T}}) where {T} = Base.iteratoreltype(T)
Base.length(f::Front) = length(f.itr) - 1
Base.eltype(f::Front{T}) where {T} = eltype(T)

:

julia> collect(Front(eachindex(rand(5))))
4-element Array{Int64,1}:
 1
 2
 3
 4

julia> collect(Front(eachindex(sprand(3, 2, .2))))
5-element Array{CartesianIndex{2},1}:
 CartesianIndex{2}((1, 1))
 CartesianIndex{2}((2, 1))
 CartesianIndex{2}((3, 1))
 CartesianIndex{2}((1, 2))
 CartesianIndex{2}((2, 2))
+5

@MattB. Front

front(itr,n=1) = (first(x) for x in Iterators.partition(itr,n+1,1))

:

julia> front(eachindex([1,2,3,4,5]))|>collect
4-element Array{Int64,1}:
 1
 2
 3
 4

:

julia> front(eachindex([1,2,3,4,5]),2)|>collect
3-element Array{Int64,1}:
 1
 2
 3

drop(eachindex([1,2,3,4,5]),2).

+1

:

for I in CartesianRange(Base.front(indices(A))) @show I A[I, :] end

A = reshape(1:27, 3, 3, 3)

I = CartesianIndex{2}((1,1)) A[I,:] = [1,10,19] I = CartesianIndex{2}((2,1)) A[I,:] = [2,11,20] I = CartesianIndex{2}((3,1)) A[I,:] = [3,12,21] I = CartesianIndex{2}((1,2)) A[I,:] = [4,13,22] I = CartesianIndex{2}((2,2)) A[I,:] = [5,14,23] I = CartesianIndex{2}((3,2)) A[I,:] = [6,15,24] I = CartesianIndex{2}((1,3)) A[I,:] = [7,16,25] I = CartesianIndex{2}((2,3)) A[I,:] = [8,17,26] I = CartesianIndex{2}((3,3)) A[I,:] = [9,18,27]

+1

Source: https://habr.com/ru/post/1675732/


All Articles