在嵌套Map中查找:sum键并更新值的Elixir实现问题
解决嵌套Map中:sum值的更新问题
首先你的原代码存在几个关键问题:
- 使用
Enum.map处理Map会返回列表,而我们需要返回处理后的Map,应该用Enum.reduce来构建新Map - 直接操作原Map的
:sum键,没有逐个处理每个键值对,递归逻辑混乱 - 用
List.first/1和List.last/1获取:bills和:coins的值依赖Map的内部顺序,非常不可靠 - 函数调用名不一致(定义的是
data,却调用data1)
以下是修正后的实现:
defmodule BcToInt do def data(map) when is_map(map) do Enum.reduce(map, %{}, fn {key, value}, acc -> updated_value = cond do # 处理:sum键,其值是包含bills和coins的Map key == :sum and is_map(value) and Map.has_key?(value, :bills) and Map.has_key?(value, :coins) -> value.bills * 100 + value.coins # 递归处理嵌套的Map is_map(value) -> data(value) # 其他值保持不变 true -> value end Map.put(acc, key, updated_value) end) end end
代码解释
- 递归遍历与构建新Map:用
Enum.reduce遍历原Map的每个键值对,逐步构建处理后的新Map,遵循Elixir不可变数据的设计原则 - :sum键的处理逻辑:当遇到键为
:sum且对应值是包含:bills和:coins的Map时,计算bills*100 + coins作为新值 - 嵌套Map递归处理:如果值本身是Map,就递归调用
data/1函数处理这个子Map - 安全的取值方式:直接通过键名
value.bills和value.coins获取值,避免依赖Map的内部存储顺序
验证测试用例
运行你提供的测试用例:
test "test1" do assert BcToInt.data(%{ count: 3, sum: %{bills: 1, coins: 99}, tax: %{count: 3, sum: %{bills: 1, coins: 1}} }) == %{count: 3, sum: 199, tax: %{count: 3, sum: 101}} end
该测试会正常通过,代码能正确处理顶层和嵌套在:tax中的:sum键。
内容的提问来源于stack exchange,提问作者Sana
相关产品推荐
相关产品推荐

