Elixir 计算每个字符的出现次数(长生不老药)?
在JS中,我可以这样做: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
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有趣。你当然是对的,对不起;-)