# Split iteration to head + tail

**URL:** https://discourse.julialang.org/t/split-iteration-to-head-tail/16406
**Category:** General Usage
**Tags:** question
**Created:** [October 16, 2018, 1:49pm UTC](https://discourse.julialang.org/t/split-iteration-to-head-tail/16406 "2018-10-16T13:49:21Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [October 16, 2018, 1:49pm UTC](https://discourse.julialang.org/t/split-iteration-to-head-tail/16406/1 "2018-10-16T13:49:21Z")

</div>

Sometimes it is necessary to handle the first element of an iterable separately, then work with the rest. I am wondering how to code these things cleanly.

To make things concrete, consider this example (calling `iterate` directly):

```julia
"""
Return the run lengths of `==` elements in the iterable itr.
"""
function runlengths(itr)
    lengths = Int[]
    y = iterate(itr)
    y ≡ nothing && return lengths
    lastelt, state = y
    runcount = 1
    while true
        y = iterate(itr, state)
        y ≡ nothing && break
        elt, state = y
        if elt == lastelt
            runcount += 1
        else
            push!(lengths, runcount)
            lastelt = elt
            runcount = 1
        end
    end
    push!(lengths, runcount)
    lengths
end

```

Example:

```julia
julia> runlengths([1,1,1,2,2,3,4,4,4])
4-element Array{Int64,1}:
 3
 2
 1
 3

```

Is there a way to code this in a cleaner way?

---

<div class="post-metadata">

### Author: ![mschauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mschauer/32/13946_2.png) [@mschauer](https://discourse.julialang.org/u/mschauer)
#### Post date: [October 16, 2018, 2:23pm UTC](https://discourse.julialang.org/t/split-iteration-to-head-tail/16406/2 "2018-10-16T14:23:10Z")

</div>

Happy to have a run here 😃

That’s pretty much why I asked for [Skipping parts of a for loop in the first iteration](https://discourse.julialang.org/t/skipping-parts-of-a-for-loop-in-the-first-iteration/16252)

With that

```julia
       """
       Return the run lengths of `==` elements in the iterable itr.
       """
       function runlengths(itr)
           lengths = Int[]
           local runcount = 1
           @unroll1 for elt in itr
               if $first
                   lastelt = elt
               else 
                   if elt == lastelt
                       runcount += 1
                   else
                       push!(lengths, runcount)
                       lastelt = elt
                       runcount = 1
                   end
               end
           end
           push!(lengths, runcount)
           lengths
       end

```

The macro there is not well tested yet though, just had to `esc` some more expression to make the example run, see  
[https://gist.github.com/mschauer/9265bd5b70c9abf1391d4ef541d53eca](https://gist.github.com/mschauer/9265bd5b70c9abf1391d4ef541d53eca)

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [October 16, 2018, 3:57pm UTC](https://discourse.julialang.org/t/split-iteration-to-head-tail/16406/3 "2018-10-16T15:57:07Z")

</div>

Use `Iterators.peel`:

```julia
function runlengths(itr)
    lengths = Int[]
    runcount = 1
    isempty(itr) && return lengths
    lastelt, rest = Iterators.peel(itr)
    for elt in rest
        if elt == lastelt
            runcount += 1
        else
            push!(lengths, runcount)
            lastelt = elt
            runcount = 1
        end
    end
    return push!(lengths, runcount)
end

```

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [October 16, 2018, 4:01pm UTC](https://discourse.julialang.org/t/split-iteration-to-head-tail/16406/4 "2018-10-16T16:01:00Z")

</div>

Unfortunately, `isempty(itr)` calls `iterate(itr)` twice.

I guess sometimes using `iterate` directly is the cleanest solution and I should not have any problems with it.

---

<div class="post-metadata">

### Author: ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)
#### Post date: [October 16, 2018, 9:21pm UTC](https://discourse.julialang.org/t/split-iteration-to-head-tail/16406/5 "2018-10-16T21:21:27Z")

</div>

I’d probably go with something similar to your original solution. It’s verbose, but I think it’s clean and easy to read.

Or, for brevity, you can do:

```julia
function runlengths(itr)
    len = Int[]
    r = foldl((v,x) -> (v[2] ≠ x[2] && push!(len, v[1]); x), enumerate(itr))
    diff(vcat(0, len, r[1]))
end

```
