带有元组修改的长生不老药列表



我正在尝试创建以下列表:

["extract-audio", "audio-format", "mp3"]

基于:

options = ["extract-audio", "audio-format": "mp3"]

我的代码从提供的options移动到首选列表:

arguments = Enum.map(options, fn(option) ->
parametrize(option)
end) |> List.flatten
def parametrize(arg) when is_tuple(arg), do: Tuple.to_list(arg)
def parametrize(arg) when is_binary(arg), do: arg

返回的列表几乎是正确的:

["extract-audio", :"audio-format", "mp3"]

但是,我不太明白分号在audio-format面前做什么.创建某种正则表达式来替换它感觉有点不对劲。有没有比我目前的实现更好的解决方案?我也考虑过地图,但在某些情况下,我只想要一个参数而不是一个键值。

你不需要任何帮助程序,只需将化简器与多个子句一起使用即可。下面的代码需要遍历列表一次,不需要平展。

options = ["extract-audio", "audio-format": "mp3"]
options
|> Enum.reduce([], fn            
{k, v}, acc -> [v, k | acc]
e, acc -> [e | acc]                   
end)
|> Enum.reverse()
#⇒ ["extract-audio", :"audio-format", "mp3"]

你可能会注意到,:"audio-format"是一个原子。那是因为Elixir用符号"foo": "bar做了一些魔法构建Keyword

["a-b": 42] == [{:"a-b", 42}]
#⇒ true

我不确定这是否是有效的方法,但这只适用于

取代

def parametrize(arg) when is_tuple(arg), do: Tuple.to_list(arg)

def parametrize(arg) when is_tuple(arg) do
for el <- Tuple.to_list(arg) do
if is_atom(el), do: Atom.to_string(el), else: el
end
end

有多种方法可以实现这一点

1. 递归

def parameterize(list, acc \ [])
def parameterize([{k, v} | tail], acc) do
parameterize(tail, [v, k | acc])
end
def parameterize([element | tail], acc) do
parameterize(tail, [element | acc])
end
def parameterize([], acc), do: acc |> List.flatten |> Enum.reverse()

2. 使用Enum.reduce,如上面阿列克谢·马蒂乌什金的回答

options = ["extract-audio", "audio-format": "mp3"]
options
|> Enum.reduce([], fn            
{k, v}, acc -> [v, k | acc]
e, acc -> [e | acc]                   
end)
|> Enum.reverse()
#⇒ ["extract-audio", :"audio-format", "mp3"]

3. 使用Enum.flat_map

Enum.flat_map(options, fn
value when is_tuple(value) -> Tuple.to_list(value)
any -> [any]
end)

根据舒适度:D可以使用这三种中的任何一种

最新更新