# An efficient way to compute the average length of streaks of a given number

**URL:** <https://discourse.julialang.org/t/an-efficient-way-to-compute-the-average-length-of-streaks-of-a-given-number/90286>\
**Category:** New to Julia\
**Created:** [November 15, 2022, 12:18pm UTC](https://discourse.julialang.org/t/an-efficient-way-to-compute-the-average-length-of-streaks-of-a-given-number/90286 "2022-11-15T12:18:11Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nash](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nash/32/14482_2.png) [@Nash](https://discourse.julialang.org/u/Nash)\
**Post date:** [November 15, 2022, 12:18pm UTC](https://discourse.julialang.org/t/an-efficient-way-to-compute-the-average-length-of-streaks-of-a-given-number/90286/1 "2022-11-15T12:18:11Z")

</div>

Suppose I have a large vector of integers ranging from 1 to 5. Now suppose I want to compute the average length of streaks of say, the number 5, where a single appearance of “5” before a different number appears, is counted as a streak of 1.

So, for example, for the vector [1,2,5,5,1,5,3,5,5,5], the average streak-length of the number 5 is (2 + 1 + 3) / 3 = 2

What is an efficient way to compute the average length of streaks of a given number in Julia?

---

<div class="post-metadata">

**Author:** ![jakobnissen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobnissen/32/13477_2.png) [@jakobnissen](https://discourse.julialang.org/u/jakobnissen)\
**Post date:** [November 15, 2022, 12:22pm UTC](https://discourse.julialang.org/t/an-efficient-way-to-compute-the-average-length-of-streaks-of-a-given-number/90286/2 "2022-11-15T12:22:53Z")

</div>

I would just take the naive approach with a simple, straight for loop:

```julia
function count_streak(pred::Function, itr)
     n_streaks, cumlen, len = 0, 0, 0
     reset(n_streaks, cumlen, len) = (n_streaks+1, cumlen+len, 0)
     for i in itr
         if pred(i)
             len += 1
         else
             if len > 0
                 (n_streaks, cumlen, len) = reset(n_streaks, cumlen, len)
             end
         end
     end
     if len > 0
        (n_streaks, cumlen, len) = reset(n_streaks, cumlen, len)
     end
     cumlen / n_streaks
 end

```

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [November 15, 2022, 12:45pm UTC](https://discourse.julialang.org/t/an-efficient-way-to-compute-the-average-length-of-streaks-of-a-given-number/90286/3 "2022-11-15T12:45:31Z")

</div>

If you want a much slower one-liner, this is one option:

```julia
mean(length(v) for v in filter(v -> v[1] == 5, collect(groupby(==(5), x))))

```

---

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [November 15, 2022, 12:47pm UTC](https://discourse.julialang.org/t/an-efficient-way-to-compute-the-average-length-of-streaks-of-a-given-number/90286/4 "2022-11-15T12:47:18Z")

</div>

I think you are looking for run length encoding, which is available in StatsBase

[https://juliastats.org/StatsBase.jl/v0.18/misc.html#StatsBase.rle](https://juliastats.org/StatsBase.jl/v0.18/misc.html#StatsBase.rle)

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [November 15, 2022, 2:05pm UTC](https://discourse.julialang.org/t/an-efficient-way-to-compute-the-average-length-of-streaks-of-a-given-number/90286/5 "2022-11-15T14:05:59Z")

</div>

Another one liner version of `count_streak`:

```julia
using IterTools

cnt_strk(p, v) = 
  sum(p.(v)) ./ (p(v[1])+sum(map(x -> <(x...), partition(p.(v), 2, 1))))

```

Test:

```julia
julia> cnt_strk(==(5),V)
1.248118414450577

julia> count_streak(==(5),V)
1.248118414450577

```

Or, the same idea but a little more code-golfy:

```julia
cnt_strk_back(p, v) = 
  ((s,t)-> s/(s-t))(sum(p.(v)), sum(map(all,partition(p.(v),2,1))))

```
