尝试做:
def nested_tuple_to_list(tuple) when is_tuple(tuple) do
...
end
期待得到:
iex> example = {"foo", "bar", {"foo", "bar"}}
iex> example_as_list = nested_tuple_to_list(example)
iex> example_as_list
["foo", "bar", ["foo", "bar"]]
我的问题是,最好的方法是什么?
答案 0 :(得分:5)
使用Tuple.to_list/1
并使用相同的函数映射结果列表,并为非元组输入添加一个回退子句:
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
输出:
["foo", "bar", ["foo", "bar"]]
如果你想在列表中转换元组,你可以添加:
def nested_tuple_to_list(list) when is_list(list) do
list |> Enum.map(&nested_tuple_to_list/1)
end
这也很容易扩展到处理地图。
答案 1 :(得分:1)
有一个库可以执行此操作以及嵌套数据的许多其他转换。
iex(1)> h PhStTransform.transform
def transform(data_structure, function_map, depth \\ [])
使用给定的function_map
转换任何Elixir data structure
。
function_map
应包含与数据类型对应的键
转化。每个键必须映射到一个函数,该函数将该数据类型和可选的深度列表作为参数。
depth
应始终保留默认值,因为它是用于内部递归。
实施例
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"]]