2017-06-27 53 views
1

傳遞字符串「word」時,我試圖打印「W-oo-rrr-dddd」(它是一個kata)。Elixir ArgumentError Enum.reduce with String concatenation

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" 

那麼,我怎樣才能使第一塊代碼工作? 感謝

+0

好像是,'String.capitalize/1'導致您的減少fn內的問題(不知道爲什麼)。如果刪除它,並保留爲'String.pad_trailing(a,i,a)',它就可以正常工作(在1.4.4中測試)。你可以放棄嗎? – matov

回答

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