Elixir更新嵌套映射中的特定值键

时间:2018-03-13 23:50:10

标签: elixir

我输入以下地图

cancel

我现在需要将密钥temp = %{"temperature" => %{ "details" => "Temperature Template", "sensors" => [ %{ "name" => "TMP", "type" => "integer", "value" => 0 }, %{ "name" => "DEEP_SLEEP", "type" => "integer", "value" => 10 } ] } } 从10更改为15与密钥"value" => 10

相关联

通过更新嵌套地图

开始
"name" => "DEEP_SLEEP"

现在尝试升级一级

new_sensor = temp  |> Map.get("temperature") |> Map.get("sensors") |> Enum.find( fn (x) -> x["name"] == "DEEP_SLEEP" end) |> Map.put("value", 15)

%{"name" => "DEEP_SLEEP", "type" => "integer", "value" => 15}

现在我应该可以用以下内容重建地图:

new_device = temp |> Map.get("temperature") |> Map.put("sensors", %{"name" => "DEEP_SLEEP", "type" => "integer", "value" => 15}) %{ "details" => "Temperature Template", "sensors" => %{"name" => "DEEP_SLEEP", "type" => "integer", "value" => 15} }

但结果不正确

Map.put(temp, "temperature", new_device)

任何帮助都是适用的

2 个答案:

答案 0 :(得分:1)

您可以在此方案中使用Kernel.put_in/3

      $(".food").on({
            click: function(){
              $(this).parent().css("text-decoration","line-through"); 
            },
            dblclick: function(){
              $(this).parent().css("text-decoration", "none"); 
            }
        });

答案 1 :(得分:0)

诀窍是更新一个数组,然后使用它的新值更新地图:

iex|1 ▶ old_value = temp["temperature"]["sensors"]
#⇒ [
#   %{"name" => "TMP", "type" => "integer", "value" => 0},
#   %{"name" => "DEEP_SLEEP", "type" => "integer", "value" => 10}
# ]

我们将明确地模式匹配函数参数,以仅使用"DEEP_SLEEP"名称更新此地图。

iex|2 ▶ new_value = Enum.map(old_value, fn                         
...|2 ▷   %{"name" => "DEEP_SLEEP"} = subj ->
...|2 ▷     %{subj | "value" => subj["value"] + 5}
...|2 ▷   subj -> subj
...|2 ▷ end)
#⇒ [
#   %{"name" => "TMP", "type" => "integer", "value" => 0},
#   %{"name" => "DEEP_SLEEP", "type" => "integer", "value" => 15}
# ]

现在我们可以使用Kernel.put_in/3来更新原始地图:

iex|3 ▶ put_in(temp, ~w|temperature sensors|, new_value)

另一种选择是使用Kernel.get_and_update_in/3