Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting nested tuple to list in elixir

Tags:

elixir

trying to do:

def nested_tuple_to_list(tuple) when is_tuple(tuple) do
  ...
end

expecting to get:

    iex> example = {"foo", "bar", {"foo", "bar"}}
    iex> example_as_list = nested_tuple_to_list(example)
    iex> example_as_list
    ["foo", "bar", ["foo", "bar"]]

my question is what is the best way to do this?

like image 396
shira Avatar asked Jan 05 '17 15:01

shira


2 Answers

Use Tuple.to_list/1 and map the resulting list with the same function, and add a fallback clause for non-tuple inputs:

defmodule A do
  def nested_tuple_to_list(tuple) when is_tuple(tuple) do
    tuple |> Tuple.to_list |> Enum.map(&nested_tuple_to_list/1)
  end
  def nested_tuple_to_list(x), do: x
end

{"foo", "bar", {"foo", "bar"}} |> A.nested_tuple_to_list |> IO.inspect

Output:

["foo", "bar", ["foo", "bar"]]

If you want to transform tuples inside lists as well, you can add:

def nested_tuple_to_list(list) when is_list(list) do
  list |> Enum.map(&nested_tuple_to_list/1)
end

This can be easily extended to handle Maps as well.

like image 84
Dogbert Avatar answered Dec 31 '22 18:12

Dogbert


There is a library that can do this and many other transforms of nested data.

iex(1)> h PhStTransform.transform

        def transform(data_structure, function_map, depth \\ [])

uses the given function_map to transform any Elixir data structure.

function_map should contain keys that correspond to the data types to be transformed. Each key must map to a function that takes that data type and optionally the depth list as arguments.

depth should always be left at the default value since it is meant for internal recursion.

Examples

iex> atom_to_string_potion = %{ Atom => fn(atom) -> Atom.to_string(atom) end }
iex> PhStTransform.transform([[:a], :b, {:c, :e}], atom_to_string_potion)
[["a"], "b", {"c", "e"}]

iex> foo = {"foo", "bar", {"foo", "bar"}}
{"foo", "bar", {"foo", "bar"}}

iex> PhStTransform.transform(foo, %{Tuple => fn(tuple) -> Tuple.to_list(tuple) end})
["foo", "bar", ["foo", "bar"]]

https://hex.pm/packages/phst_transform

like image 42
Fred the Magic Wonder Dog Avatar answered Dec 31 '22 19:12

Fred the Magic Wonder Dog