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?
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With