Skip to content

Instantly share code, notes, and snippets.

@heri16
Created August 26, 2021 16:19
Show Gist options
  • Save heri16/e726ee7f335d2ca61bbbb016e6b884e1 to your computer and use it in GitHub Desktop.
Save heri16/e726ee7f335d2ca61bbbb016e6b884e1 to your computer and use it in GitHub Desktop.
Elixir Flatten array (with tail recursion)
defmodule FlattenArray do
@doc """
Accept a list and return the list flattened without nil values.
## Examples
iex> FlattenArray.flatten([1, [2], 3, nil])
[1,2,3]
iex> FlattenArray.flatten([nil, nil])
[]
"""
@spec flatten(list) :: list
def flatten([]), do: [] # optimization
def flatten(l), do: flatten([], [], l)
def flatten(acc, [], []), do: Enum.reverse(acc) # reversing an accumulated list is fast in EVM
def flatten(acc, queue, []), do: flatten(acc, [], queue) # process queue once element is empty
def flatten(acc, queue, [nil | t]), do: flatten(acc, queue, t) # skip nil
def flatten(acc, queue, [[] | t]), do: flatten(acc, queue, t) # skip empty list
def flatten(acc, queue, [h | t]) when is_list(h), do: flatten(acc, [t | queue], h) # push tail into queue, and process element
def flatten(acc, queue, [h | t]), do: flatten([h | acc], queue, t) # put element into accumulator
end
@heri16
Copy link
Author

heri16 commented Dec 1, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment