Enum.reduce中的Elixir ArgumentError与字符串连接

时间:2017-06-27 14:32:22

标签: elixir

当传递字符串“word”时,我正在尝试打印“W-oo-rrr-dddd”(这是一个kata)。

String.graphemes(word) |> Enum.with_index(1) |> Enum.reduce(
  fn
    ({a, 1}, _) -> String.capitalize(a)
    ({a, i}, acc) -> acc <> "-" <> String.pad_trailing(String.capitalize(a), i, String.downcase(a))
  end
)

但我明白了:

** (ArgumentError) argument error
lib/katas.ex:12: anonymous fn/2 in Katas.accum/1
(elixir) lib/enum.ex:1755: Enum."-reduce/2-lists^foldl/2-0-"/3
lib/katas.ex:9: Katas.accum/1
(stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
(elixir) lib/code.ex:170: Code.eval_string/3

但是,如果我从第二个函数匹配中取出累加器并置,则不会引发错误(尽管代码现在是错误的)

String.graphemes("word") |> Enum.with_index(1) |> Enum.reduce(
  fn
    ({a, 1}, _) -> String.capitalize(a)
    ({a, i}, _) -> String.pad_trailing(String.capitalize(a), i, String.downcase(a))
  end
)

然而,字符串连接似乎工作正常:

iex(73)> Enum.reduce(["StringA", "StringB"], fn(x, acc) -> acc <> "-" <> x end)
"StringA-StringB"

那么,我怎样才能使第一段代码工作? 感谢

1 个答案:

答案 0 :(得分:1)

您需要将累加器的初始值指定为"",否则将其设置为列表的第一项,这意味着累加器以元组{"w", 1}开始,当你尝试将它用作字符串时,你会得到参数错误。

word = "word"
String.graphemes(word) |> Enum.with_index(1) |> Enum.reduce(
  "",
  fn
    ({a, 1}, _) -> String.capitalize(a)
    ({a, i}, acc) -> acc <> "-" <> String.pad_trailing(String.capitalize(a), i, String.downcase(a))
  end
)
|> IO.inspect

输出:

"W-Oo-Rrr-Dddd"

我还建议在这里使用Enum.map_join/3来获得更优雅的(IMO)代码:

word = "word"
String.graphemes(word)
|> Enum.with_index(1)
|> Enum.map_join(
  "-",
  fn
    {a, 1} -> String.capitalize(a)
    {a, i} -> String.pad_trailing(String.capitalize(a), i, String.downcase(a))
  end
)
|> IO.inspect