Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Elixir 使用多个键更新嵌套映射_Elixir - Fatal编程技术网

Elixir 使用多个键更新嵌套映射

Elixir 使用多个键更新嵌套映射,elixir,Elixir,假设我们有这样的地图: state = %{ data: %{ "default" => %{ "someKeyword" => %{updated: 2}}, "baila" => %{ "someKeyword" => %{updated: 2}}, "morena" => %{updated: 2} } } 在本例

假设我们有这样的地图:

state = %{
      data: %{
        "default" => %{
          "someKeyword" => %{updated: 2}},

          "baila" => %{
            "someKeyword" => %{updated: 2}},
            "morena" => %{updated: 2}
        }
      }
在本例中,只需检查两个“父键”->
default
baila
,在实际应用程序中,将有100个+

现在,当我使用更新的关键字
someKeyword
获取事件时,如何检查所有父关键字,并在找到关键字且新关键字的某些值高于旧关键字的值时有条件地更新

比如:

newKeyword = %{"someKeyword" => %{updated: 3, otherdata: 4}}
newKeywordkey = List.first(Map.keys(newKeyword))

keys = Map.keys(state.data)

Enum.each(keys, fn(x) ->
  new_state = case Kernel.get_and_update_in(x, [newKeywordkey], fn(y) ->
    if y.updated < newKeyword[newKeywordkey] do
         ....
     end
    {y, newKeyword}
  end)
   do
    {l, b} -> b
  end
end)
以下是使用和的一种方法:

输出:

%{data: %{"baila" => %{"morena" => %{updated: 2},
      "someKeyword" => %{otherdata: 4, updated: 3}},
    "default" => %{"someKeyword" => %{otherdata: 4, updated: 3}}}}

虽然@Dogbert的答案绝对正确(尽管它对一个键值对有效,但有一个限制),但有更简单的方法来实现目标

new_data = %{"someKeyword" => %{updated: 3, otherdata: 4}}
%{data: state.data 
  |> Enum.map(fn {k, v} -> 
       {k, 
        (if v["someKeyword"] == nil ||
            v["someKeyword"][:updated] == nil ||
            v["someKeyword"][:updated] < new_data[:updated],
         do: v |> Map.merge(new_keyword), else: v)
       }
     end)
  |> Enum.into(%{})}

#⇒ %{data: %{"baila" => %{"morena" => %{updated: 2},
#       "someKeyword" => %{otherdata: 4, updated: 3}},
#     "default" => %{"someKeyword" => %{otherdata: 4, updated: 3}}}}
new_data=%{“someKeyword”=>%{updated:3,otherdata:4}
%{data:state.data
|>枚举映射(fn{k,v}->
{k,
(如果v[“someKeyword”]==nil||
v[“someKeyword”][:updated]==nil||
v[“someKeyword”][:updated]<新数据[:updated],
do:v |>Map.merge(新的_关键字),else:v)
}
(完)
|>Enum.into(%{})
#⇒%%{数据:%%{“baila”=>%%{“morena”=>%{更新:2},
#“someKeyword”=>%{otherdata:4,更新:3},
#“默认值”=>%{“someKeyword”=>%{otherdata:4,更新:3}}
上述操作可用于合并任何新的数据映射


感谢@Dogbert指出这里需要更新的
的显式条件。

我找到了一个非常简单的方法,请参阅


如果与
someKeyword
关联的值对于所有子映射都是相同的,那么将其存储在不同的级别是否有意义呢?我认为这不会处理“如果找到了键并且新键的某些值高于旧键的值,则进行更新”,但是如果使用
Map.merge/3
和简单的
If
,我认为它的功能与我的代码相同,而且肯定会更干净。我一直使用这一个,因为它非常清晰简洁:)
%{data: %{"baila" => %{"morena" => %{updated: 2},
      "someKeyword" => %{otherdata: 4, updated: 3}},
    "default" => %{"someKeyword" => %{otherdata: 4, updated: 3}}}}
new_data = %{"someKeyword" => %{updated: 3, otherdata: 4}}
%{data: state.data 
  |> Enum.map(fn {k, v} -> 
       {k, 
        (if v["someKeyword"] == nil ||
            v["someKeyword"][:updated] == nil ||
            v["someKeyword"][:updated] < new_data[:updated],
         do: v |> Map.merge(new_keyword), else: v)
       }
     end)
  |> Enum.into(%{})}

#⇒ %{data: %{"baila" => %{"morena" => %{updated: 2},
#       "someKeyword" => %{otherdata: 4, updated: 3}},
#     "default" => %{"someKeyword" => %{otherdata: 4, updated: 3}}}}
my_map = %{
  foo: %{
    bar: %{
      baz: "my value"
    }
  }
}

put_in(my_map, [:foo, :bar, :baz], "new value")