Elixir 计算每个字符的出现次数(长生不老药)?

Elixir 计算每个字符的出现次数(长生不老药)?,elixir,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

在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
}
函数countIt(str){
设obj={};
for(设i=0;i
考虑到Elixir中每个字符的不变性,使用
Map
计算每个字符出现次数的最佳方法是什么

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

“你好,世界”
|>String.graphemes()
|>Enum.reduce(%{},fn char,acc->
地图放置(acc,char,(acc[char]| | 0)+1)
(完)
#⇒ %{'=>1,“H”=>1,“W”=>1,“d”=>1,
#“e”=>1,“l”=>3,“o”=>2,“r”=>1}

或(计入@Dogbert)使用:

“你好,世界”
|>String.graphemes()
|>Enum.reduce(%{},fn char,acc->
地图更新(acc、char、1和1+1))
(完)

或者,更惯用的方法是,基于模式匹配减缩器参数来确定是否应该添加或启动计数器:

“你好,世界”
|>String.graphemes()
|>Enum.reduce(%{},fn char,acc->
案例acc do
%{^char=>count}->%{acc | char=>count+1}
_->映射放置(acc,char,1)
结束
(完)

实现这一点的另一种方法是使用尾部递归函数。此函数不会向堆栈中添加更多帧,因为在运行时,该函数将返回到自身顶部,而不是进行另一次调用。为了实现这一点,您需要有一个累加器函数,如
\u count

defmodule Kitten do
  def count(word) do
    word
    |> _count
  end

  defp _count("", acc), do: acc

  defp _count(<<head::utf8, tail::binary>>, acc \\ %{}) do
    updated_acc = Map.update(acc, <<head>>, 1, &(&1 + 1))
    _count(tail, updated_acc)
  end
end
defmodule Kitten do
def计数(word)do
单词
|>_计数
结束
除霜计数(“,acc),do:acc
defp_计数(,acc\\%{})do
更新后的附件=地图更新(附件1和1+1))
_计数(尾部,更新的_acc)
结束
结束
考虑到地图在长生不老药中的不变性,使用地图计算每个角色出现次数的最佳方法是什么?函数式语言解决这类问题的一般策略是什么

您可以使用并获得更清晰的代码:

计数。exs

defmodule Count do
def count_it(str)do
str
|>新地图(&{,
枚举计数(str,fn x->&1==x end)}
)
结束
结束
测试它:
iex count.exs

iex(1)>Count.Count\u it('hello'))
%{“e”=>1,“h”=>1,“l”=>2,“o”=>1}
iex(2)>

使用
Elixir-1.10
您可以在一行中使用Enum.frequencies函数@Dogbert完成此操作非常感谢,更新了,我不知道
Map.update/4
。您上一个示例中的附加
案例
,实际上没有必要,您可以直接将模式匹配与
fn
一起使用。@PatrickOscity-negative。贴图关键点只能与预定义(固定)变量匹配
fn char,%{char=>}
引发
CompileError
@mudasobwa有趣。你当然是对的,对不起;-)