Ilya Suzdalnitski
Ilya Suzdalnitski

Reputation: 53540

How do I flatten a nested list in Elixir?

I have a nested list [1, [2, [3, 4], 5], 6]. How do I flatten it, so that it becomes [1, 2, 3, 4, 5, 6]?

Upvotes: 11

Views: 8050

Answers (3)

MoVod
MoVod

Reputation: 1121

Here's a good old recursive way (not tail-call optimised)

defmodule Test do
  # degenerate case
  def flatten([]), do: []

  # list with more than 1 elt
  def flatten([ head | tail ]) do
    flatten(head) ++ flatten(tail)
  end
  
  # list with only one elt
  def flatten(head), do: [ head ]
done

Upvotes: 1

Adam Millerchip
Adam Millerchip

Reputation: 23091

No need to re-invent the wheel, just use List.flatten/1

iex(1)> List.flatten([1, [2, [3, 4], 5], 6])
[1, 2, 3, 4, 5, 6]

Upvotes: 25

Ilya Suzdalnitski
Ilya Suzdalnitski

Reputation: 53540

defmodule Util do
  @doc """
  Flattens nested lists

  ## Examples
    iex> Util.flatten_nested([1, [2, [3, 4], 5], 6])
    [1, 2, 3, 4, 5, 6]
  """
  def flatten_nested(list, acc \\ []),
    do: flatten_nested_rev(list, acc) |> Enum.reverse()

  @doc """
  Flattens nested lists, and returns a reversed list

  ## Examples
    iex> Util.flatten_nested_rev([1, [2, [3, 4], 5], 6])
    [6, 5, 4, 3, 2, 1]
  """
  def flatten_nested_rev(list, acc \\ [])

  def flatten_nested_rev([], acc) do
    acc
  end

  def flatten_nested_rev([list | rest], acc) when is_list(list) do
    flatten_nested_rev(rest, flatten_nested_rev(list, acc))
  end

  def flatten_nested_rev([element | rest], acc) do
    flatten_nested_rev(rest, [element | acc])
  end
end

Upvotes: -4

Related Questions