Using Iterators.rest to iterate over a range

Can anyone explain why

Iterators.rest([1, 2, 3], 2) |> collect

results in

2-element Array{Int64,1}:
 2
 3

but

Iterators.rest(1:3, 2) |> collect

returns

1-element Array{Int64,1}:
 3

?

It is because Array and UnitRange handle their iteration state differently. For Array, the returned state is the index of the next element, for UnitRange, it is the value of the current element (ranges do arithmetic on their values for iteration, their indices are not used):

julia> iterate([1,2,3])
(1, 2)

julia> iterate(1:3)
(1, 1)

julia> iterate([4,5,6])
(4, 2)

julia> iterate(4:6)
(4, 4)

Since the second argument to Iterators.rest is the iteration state, this is not portable between Arrays and UnitRanges.

1 Like

great, thanks!

FYI: Iterators.drop will skip a specified number of elements at the start of an iterator, regardless of how the iteration is implemented internally.

1 Like