Normally you should use the stdlib if there is some help there (most of the time there is, in this case chunk_by/2
can do all the hard work). But you can also do it by hand…
defmodule Chunker do
def chunk([]), do: []
def chunk([head|tail]), do: _chunk(tail, [], 1, head)
# this is the stop condition, all elements of the input are consumed
defp _chunk([], acc, count, _), do: acc ++ [count]
# this function only matches when the head of the list is the same as the last
# you just have to give them the same name ("last") - nice, isn't it?
defp _chunk([last|tail], acc, count, last), do: _chunk(tail, acc, count+1, last)
# a new chunk begins!
defp _chunk([head|tail], acc, count, _last), do: _chunk(tail, acc ++ [count], 1, head)
end
Note: this is slow for large lists because of
acc ++ [count]
In each of those, the whole acc
-list is walked until the end is found.
Can be optimized by
[count] ++ acc
and a new stop condition:
defp _chunk([], acc, count, _), do: Enum.reverse([count] ++ acc)