带有元组修饰的药剂列表

问题描述 投票:0回答:3

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

["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前面的分号在做什么。创建某种正则表达式来代替它有点不舒服。是否有比我当前的实施更好的解决方案?我也考虑过地图,但是在某些情况下,我只想要一个参数而不是键值。

elixir
3个回答
3
投票

您不需要任何帮助程序,只需将reducer与多个子句一起使用。下面的代码需要遍历列表,并且不需要展平。

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用符号Keyword进行了一些魔法构建Keyword

"foo": "bar

0
投票

我不确定这是否有效,但这是可行的

替换

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

with

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

0
投票

有多种实现方法

1。递归

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

2。使用Enum.reduce由上面的Aleksei Matiushkin回答

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()

3。使用Enum.flat_map

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"]

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

© www.soinside.com 2019 - 2024. All rights reserved.