# How to apply \`Iterators.drop\` on an \`Iterators.Stateful\`?

**URL:** <https://discourse.julialang.org/t/how-to-apply-iterators-drop-on-an-iterators-stateful/27144>\
**Category:** General Usage\
**Tags:** question\
**Created:** [August 4, 2019, 3:56am UTC](https://discourse.julialang.org/t/how-to-apply-iterators-drop-on-an-iterators-stateful/27144 "2019-08-04T03:56:00Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![singularitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/singularitti/32/17678_2.png) [@singularitti](https://discourse.julialang.org/u/singularitti)\
**Post date:** [August 4, 2019, 3:56am UTC](https://discourse.julialang.org/t/how-to-apply-iterators-drop-on-an-iterators-stateful/27144/1 "2019-08-04T03:56:00Z")

</div>

See the following MWE:

```julia
julia> a = Iterators.Stateful("123456789");

julia> b = Iterators.drop(a, 3)
Base.Iterators.Drop{Base.Iterators.Stateful{String,Union{Nothing, Tuple{Char,Int64}}}}(Base.Iterators.Stateful{String,Union{Nothing, Tuple{Char,Int64}}}("123456789", ('1', 2), 0), 3)

julia> iterate(b)
('4', nothing)

julia> iterate(b)
('8', nothing)

julia> iterate(b)
# nothing

```

Variable `b` drops the first 3 elements of `a` every time iterating it.  
But what I want is actually drop the “123” and iterate `a` one by one.  
A working way could be

```julia
julia> a = Iterators.Stateful("123456789");

julia> b = Iterators.Stateful(collect(Iterators.drop(a, 3)))
Base.Iterators.Stateful{Array{Char,1},Union{Nothing, Tuple{Char,Int64}}}(['4', '5', '6', '7', '8', '9'], ('4', 2), 0)

julia> iterate(b)
('4', nothing)

julia> iterate(b)
('5', nothing)

julia> iterate(b)
('6', nothing)
...

```

But if `a` is large of infinitive, `collect`ing is not possible.

Of course, I could write, in this example,

```julia
julia> a = Iterators.Stateful(Iterators.drop("123456789", 3));

julia> iterate(a)
('4', nothing)

julia> iterate(a)
('5', nothing)

julia> iterate(a)
('6', nothing)

```

from the beginning, but sometimes this is not possible. I am given `a` as a `Stateful` already.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [August 4, 2019, 12:34pm UTC](https://discourse.julialang.org/t/how-to-apply-iterators-drop-on-an-iterators-stateful/27144/2 "2019-08-04T12:34:09Z")

</div>

Maybe `Iterators.rest`? See [here](https://docs.julialang.org/en/v1/base/iterators/index.html#Base.Iterators.rest).

What’s crucial is understanding that each function from `Iterators` returns a new iterator wrapping whatever you gave to it and that nested iterators are applied one after the other.

---

<div class="post-metadata">

**Author:** ![singularitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/singularitti/32/17678_2.png) [@singularitti](https://discourse.julialang.org/u/singularitti)\
**Post date:** [August 5, 2019, 6:35am UTC](https://discourse.julialang.org/t/how-to-apply-iterators-drop-on-an-iterators-stateful/27144/3 "2019-08-05T06:35:23Z")

</div>

> [@singularitti](#):
>
> Iterators.drop(a, 3)

It seems to work:

```julia
julia> a = Iterators.Stateful("123456789")
Base.Iterators.Stateful{String,Union{Nothing, Tuple{Char,Int64}}}("123456789", ('1', 2), 0)

julia> b = Iterators.drop(a, 3)
Base.Iterators.Drop{Base.Iterators.Stateful{String,Union{Nothing, Tuple{Char,Int64}}}}(Base.Iterators.Stateful{String,Union{Nothing, Tuple{Char,Int64}}}("123456789", ('1', 2), 0), 3)

julia> for x in Iterators.rest(b)
           println(x)
       end
4
5
6
7
8
9

```

Thank you!

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [August 5, 2019, 7:16am UTC](https://discourse.julialang.org/t/how-to-apply-iterators-drop-on-an-iterators-stateful/27144/4 "2019-08-05T07:16:46Z")

</div>

I was thinking more along the lines of `Iterators.rest(a,3)` instead of `drop` altogether, since that is the explicit purpose of the `rest` iterator.

---

<div class="post-metadata">

**Author:** ![singularitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/singularitti/32/17678_2.png) [@singularitti](https://discourse.julialang.org/u/singularitti)\
**Post date:** [August 5, 2019, 7:36am UTC](https://discourse.julialang.org/t/how-to-apply-iterators-drop-on-an-iterators-stateful/27144/5 "2019-08-05T07:36:13Z")

</div>

> [@singularitti](#):
>
> for x in Iterators.rest(b) println(x) end

Oh, I guess it does not work so simple for a `Stateful`:

```julia
julia> a = Iterators.Stateful("123456789")
Base.Iterators.Stateful{String,Union{Nothing, Tuple{Char,Int64}}}("123456789", ('1', 2), 0)

julia> for x in Iterators.rest(a, 3)
           println(x)
       end
1
2
3
4
5
6
7
8
9

```

It does work if `a` is just a normal iterable:

```julia
julia> a = "123456789"
"123456789"

julia> for x in Iterators.rest(a, 3)
           println(x)
       end
3
4
5
6
7
8
9

```

---

<div class="post-metadata">

**Author:** ![rapus95](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rapus95/32/3773_2.png) [@rapus95](https://discourse.julialang.org/u/rapus95)\
**Post date:** [August 11, 2021, 10:20am UTC](https://discourse.julialang.org/t/how-to-apply-iterators-drop-on-an-iterators-stateful/27144/6 "2021-08-11T10:20:56Z")

</div>

Stumbling over this and seeing it as unsolved given that the marked solution doesn’t help to understand the original problem, I feel the urge to correct a few things:

1. `Iterators.rest` is not for skipping or dropping elements. I’d even advise against using `Iterators.rest` unless you know exactly how the iterator tracks state because the 2nd argument of the rest function is a state object. Having that work here is coincidental luck, since for strings and arrays, state is tracked by index. But in case of the Stateful iterator, the 2nd argument doesn’t have any effect since Stateful iterators don’t need it to work given the internal state (though, they need a 2nd argument in order to fulfill the protocol).

2. The only problem in the initial MWE was that you call the single argument `iterate` function whose sole purpose is to start an iteration (which in the case of `drop` drops n values).  
So for all follow-up calls to iterate there should be a 2nd argument. Or worded differently, proper use of the iteration protocol works flawlessly here.

```julia
iter = Iterators.drop(Iterators.Stateful("123456789"), 3)
for x in iter
  println(x)
end

```

should work as intended.  
if you want to step over it manually, then you need to feed the state of the previous iteration into the iterate function:

```julia
iter = Iterators.drop(Iterators.Stateful("123456789"), 3)
next = iterate(iter)
while next!==nothing
  elem, state = next
  println(elem)
  next = iterate(iter, state)
end

```

Sorry for reviving it. But given that one can still stumble over this (as I did) I felt the urge to correct some aspects 🙈
