我的理解是,地图实现了收集器协议,因此可以用于into:
理解部分。为了尝试这个,我编写了以下程序:
lt = [{"ab", "cd", "ef"}, {"x", "y", "z"}]
m = %{}
for c <- lt, into: m do
IO.puts(length(Map.keys(m)))
{elem(c,1),elem(c,0)}
end
IO.puts(length(Map.keys(m)))
我预计这m
会在最后设定%{"cd" => "ab", "y" => "x"}
并看到
0
1
2
正在打印,但我打印了0
三遍。地图上似乎什么也没有收集到m
。为什么?
您忘记了变量是不可变的:您需要使用并保留
for
.该变量
m
将保持为空map
,不会被修改也不会反弹。事实上,它只是设置了累加器的初始值,所以这里使用变量不是很有用,你可以直接写into: %{}
.如果您想获取累积值,因为
for
它会为您处理并且不会公开它,您必须使用:reduce
Hauleth 所示的内容,这相当于Enum.reduce/3
您喜欢的方式:因为这就是
:into
期权的运作方式。您的代码在逻辑上相当于正如您所看到的,任何地方都没有修改
m
。您可能想要的是:这将导致您想要的行为。
Elixir 中的值是不可变的。
然而,它们可以反弹:
因此,虽然您无法改变值内部包含的内容,但您可以重新绑定变量指向的内容。
在上述情况下
Map.put
,该操作返回一个新的数据结构,表示map
应用了更改的原始数据结构,而不影响原始映射。如果要保留结果,则需要将其分配回变量:在您的示例中,理解正在收集值,但您没有将结果分配给变量,并且原始值
m
保持不变。