计算每个炭(Elixir)的发生次数?

Igg*_*ggy 1 elixir

在JS中,我可以这样做:

function countIt(str){
  let obj = {};
  for(let i = 0; i < str.length; i++){
    if(!obj[str[i]]){
      obj[str[i]] = 1;
    } else {
      obj[str[i]]++;
    }
  }
  return obj;
}

console.log(countIt("hello"));
//returns {
  e: 1,
  h: 1,
  l: 2,
  o: 1
}
Run Code Online (Sandbox Code Playgroud)

Map考虑到其不变性,在Elixir中计算每个角色出现次数的最佳方法是什么?函数式语言解决此类问题的一般策略是什么?

Ale*_*kin 8

函数式语言解决此类问题的一般策略是什么?

Enum.reduce/3

"Hello World"
|> String.graphemes()
|> Enum.reduce(%{}, fn char, acc ->
     Map.put(acc, char, (acc[char] || 0) + 1)
   end)
#? %{" " => 1, "H" => 1, "W" => 1, "d" => 1,
#    "e" => 1, "l" => 3, "o" => 2, "r" => 1}
Run Code Online (Sandbox Code Playgroud)

或(信用@Dogbert)使用Map.update/4:

"Hello World"
|> String.graphemes()
|> Enum.reduce(%{}, fn char, acc ->
     Map.update(acc, char, 1, &(&1 + 1))
   end)
Run Code Online (Sandbox Code Playgroud)

或者,也许更惯用,基于模式匹配reducer参数来确定我们是否应该添加或启动计数器:

"Hello World"
|> String.graphemes()
|> Enum.reduce(%{}, fn char, acc ->
     case acc do
       %{^char => count} -> %{acc | char => count + 1}
       _ -> Map.put(acc, char, 1)
     end
   end)
Run Code Online (Sandbox Code Playgroud)

  • 我会做`Map.update(acc,char,1,&(&1 + 1))`. (3认同)