如何在Elixir中更高效地合并两个包含Map的列表?
高效合并两个列表的Elixir实现方案
嘿,这个问题我之前也处理过,要高效合并这两个列表的关键是先把list1转换成一个快速查找的映射表,避免嵌套遍历带来的性能损耗。咱们一步步来:
核心思路
list1里是单个id对应的金额,list2是分组的id集合。如果直接嵌套遍历两个列表去匹配id,数据量大的时候会非常慢。所以先把list1转成以id为键、amount为值的Map,这样后续查找每个id的金额都是O(1)的时间复杂度,整体效率会提升很多。
具体实现代码
第一步:构建id到金额的映射表
先把list1转换成Map,方便快速查找:
# 处理list1,生成id => amount的映射 id_amount_map = Enum.into(list1, %{}, fn %{id: id, amount: amount} -> {id, amount} end)
如果list1里存在重复id(比如同一个id出现多次,金额需要累加),那就要用Enum.reduce先汇总相同id的总金额:
id_amount_map = Enum.reduce(list1, %{}, fn %{id: id, amount: amount}, acc -> Map.update(acc, id, amount, &(&1 + amount)) end)
第二步:遍历list2并合并金额
接下来遍历list2的每个分组,计算该分组下所有在list1中存在的id的总金额,然后把总金额合并到原分组中:
merged_list = Enum.map(list2, fn group -> # 计算当前分组的总金额:过滤出在映射表中存在的id,然后累加金额 total_amount = group.id |> Enum.filter(&Map.has_key?(id_amount_map, &1)) |> Enum.reduce(0, fn id, acc -> acc + id_amount_map[id] end) # 把总金额添加到原分组Map中,这里用Map.put/3实现 Map.put(group, :total_amount, total_amount) end)
效率说明
这个方案的时间复杂度是O(len(list1) + len(list2) * 平均每个分组的id数量),相比嵌套遍历的O(len(list1)*len(list2)),在数据量较大时性能提升非常明显。比如当list1有1000个元素,list2有100个分组每个分组有10个id,嵌套遍历需要10001000=1e6次操作,而这个方案只需要1000 + 10010=1100次操作,差距很大。
内容的提问来源于stack exchange,提问作者Elmseld
相关产品推荐
相关产品推荐

