Packages

Identifies consecutive elements within a given list of elements

Current section

Files

Jump to
consecutix lib consecutix.ex
Raw

lib/consecutix.ex

defmodule Consecutix do
@moduledoc """
Documentation for `Consecutix`.
"""
@doc """
Returns consecutively grouped elements.
Returned elements will be sorted.
Duplicated elements are deleted.
## Examples
iex> Consecutix.consecutive_lists([])
[]
iex> Consecutix.consecutive_lists([1])
[[1]]
iex> Consecutix.consecutive_lists([1, 2])
[[1, 2]]
iex> Consecutix.consecutive_lists([1, 3])
[[1], [3]]
"""
@spec consecutive_maps(list(map)) :: [list()]
def consecutive_maps([]) do
[]
end
@type input :: list()
@type output :: [list()]
@type sorter :: fun()
@spec consecutive_lists(input, sorter) :: output
def consecutive_lists(list, sorter \\ &Enum.sort/1)
def consecutive_lists(list, sorter) when is_function(sorter, 2) do
list |> Enum.sort(sorter) |> consecutive_lists_helper([], [])
end
def consecutive_lists(list, sorter) when is_function(sorter, 1) do
list |> sorter.() |> consecutive_lists_helper([], [])
end
defp consecutive_lists_helper([], [], result), do: Enum.reverse(result)
defp consecutive_lists_helper([], current_group, result),
do: Enum.reverse([Enum.reverse(current_group) | result])
defp consecutive_lists_helper([current | tail], [], result) do
consecutive_lists_helper(tail, [current], result)
end
defp consecutive_lists_helper([current | tail], [prev | _] = current_group, result)
when current - prev == 1 do
consecutive_lists_helper(tail, [current | current_group], result)
end
defp consecutive_lists_helper([current | tail], current_group, result) do
consecutive_lists_helper(tail, [current], [Enum.reverse(current_group) | result])
end
end