You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Collector的Elixir推导未收集数据:Map为何未被填充?

问题原因与解决方法

你的问题核心是没搞清楚Elixir的不可变特性,以及for推导中into:参数的工作逻辑,具体拆解如下:

  1. Map确实支持into:参数,但不会修改原变量
    Map实现了Collector协议,所以into:可以传入Map,但Elixir是纯不可变语言——你传入into: m时,推导会基于初始的空Map创建新的Map,而完全不会修改原来绑定的m变量。你最后输出的m还是最开始的空Map,自然长度为0。

  2. 循环体内访问的是初始的空Map
    循环里的m是代码最开始绑定的那个空Map,每次迭代都不会变,所以三次输出都是0。

  3. 必须接收for推导的返回值
    for推导的返回值才是收集完成后的新Map,你没有接收这个值,所以看不到预期的结果。


修正后的代码

lt = [{"ab", "cd", "ef"}, {"x", "y", "z"}]
initial_m = %{}
# 接收推导返回的新Map
new_m = for c <- lt, into: initial_m do
  {elem(c, 1), elem(c, 0)}
end

IO.puts(length(Map.keys(new_m))) # 输出2
IO.inspect(new_m) # 输出 %{"cd" => "ab", "y" => "x"}

如果需要在迭代过程中跟踪当前收集的进度,因为不可变特性没法直接访问构建中的集合,可以用索引或者Enum.reduce实现:

lt = [{"ab", "cd", "ef"}, {"x", "y", "z"}]
{final_m, _} = Enum.reduce(lt, {%{}, 0}, fn c, {acc, count} ->
  IO.puts(count) # 依次输出0、1
  new_acc = Map.put(acc, elem(c, 1), elem(c, 0))
  {new_acc, count + 1}
end)

IO.puts(length(Map.keys(final_m))) # 输出2
IO.inspect(final_m)

内容的提问来源于stack exchange,提问作者user1934428

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 07:03:18