For my first approach to AoC day 7, I needed a way to flatten a multi-dimensional list, down to just 2-dimensional. (Before you say anything: Now that I solved it, I already have a better approach that won’t need this.)
List.flatten/1
goes too far; what I needed was this (2-element example shown, but I tested this and it works for larger sizes/depths too):
@doc ~S"""
## Examples
iex> flatten_2d([[[[:a, :b],[:c, :d]],[[:e, :f],[:g, :h]]],[[[:i, :j],[:k, :l]],[[:m, :n],[:o, :p]]]])
[[:a, :b], [:c, :d], [:e, :f], [:g, :h], [:i, :j], [:k, :l], [:m, :n], [:o, :p]]
"""
@spec flatten_2d([[]]) :: [[]]
def flatten_2d([h | t]) when is_list(h) do
if is_list(List.first(h)) do
[h | t]
|> Enum.map(&flatten_2d/1)
|> Enum.concat()
else
[h | t]
end
end
I couldn’t find anything in List
or Enum
that seemed to do this, so I wrote the above. Is there an existing or better way to do this?