首页 > 解决方案 > 长生不老药map.put不更新地图

问题描述

我有一个以 Map%{}作为参数的函数

def set_data (data) do
...
end

我正在尝试data使用map.put.

data是这样的平面地图

%{
 a: ...
 b: ...
 c: ...
}

我有一个问题是在data地图中设置一个键/属性与另一个看起来像这样的地图:

ModuleA.EctoSchemaMap{
 some_key: nil,
 another_key: ModuleB.EctoSchemaMap{
  inner_key_a: "456",
  inner_key_b: nil
 }
}

上面的这张地图ModuleA.EctoSchemaMap是从这样的函数调用中返回的

some_data = get_data()

所以some_data=ModuleA.EctoSchemaMap上面的地图。

出于某种原因,当我尝试在函数中更新b参数data映射中的键时,所有内容都会复制映射中的nilModuleA.EctoSchemaMap,但键inner_key_a也显示为 nil,即使之前some_data显示inner_key_a不是nil

data
|> map.put(:a, "123")
|> map.put(:b, some_data)

在完成上面的管道之后,我期望data已经:b更新了该值

b: ModuleA.EctoSchemaMap{
    some_key: nil,
    another_key: ModuleB.EctoSchemaMap{
     inner_key_a: "456", //I need this value to be there
     inner_key_b: nil
    }
   }

但它反而显示了这个

b: ModuleA.EctoSchemaMap{
    some_key: nil,
    another_key: ModuleB.EctoSchemaMap{
     inner_key_a: nil, //NOT sure why this is being set as nil even though `some_data` had a value for this
     inner_key_b: nil
    }
   }

标签: elixir

解决方案


Elixir 中的所有数据结构都是不可变的。在代码中,Map.put使用添加/更新的给定键值创建地图的新副本。但它不会存储在任何地方。所以,重新分配变量data_map

data_map = data_map
|> map.put(:some_key, data)

由于您在管道中只有一项操作,因此推荐的方法是 -

data_map = Map.put(data_map, :some_key, data)

另请注意,它Map不是map.


推荐阅读