在嵌套映射中动态添加键值对

Adding key value pair in a nested map dynamically

我有这张地图:

           %{
             "$include" => %{
                "hospitals" => %{
                   "$include" => %{"rooms" => %{"beds" => %{}}},
                   "$order" => %{"id" => "$asc"}
                },
               "doctors" => %{
                   "$order" => %{"id" => "$desc"}                      
                }
             }
          }

$include 中嵌套了任意数量的 $include 语句。所以它应该是动态的。输出应该是。

           %{
             "$include" => %{
                "hospitals" => %{
                   "$include" => %{"rooms" => %{"beds" => %{"binding" => "last"}, "binding" => "last"}},
                   "$order" => %{"id" => "$asc"},
                   "binding" => "first"
                },
               "doctors" => %{
                   "$order" => %{"id" => "$desc"},
                   "binding" => "first"
                }
             }
          }

所有外部映射应包含 binding => "first",所有嵌套包含应包含 "binding "=> "last".

我试过使用 Enum.reduce,但无法正常工作

    Enum.reduce(params, %{}, fn {k, v}, acc ->
      v = Map.put(v, "binding", "last")
      Map.put(acc, k, if(is_map(v["$include"]), do: 
        add_bindings(v["$include"]), else: v))
    end) 

任何帮助将不胜感激。

谢谢

您可以像这样迭代 nasted 映射(我注意到带有 $ 的映射不应包含 binding 键):

def add_bindings(data, outer \ true) when data |> is_map do
  data
  |> Enum.reduce(%{}, fn {key, value}, acc ->
    acc
    |> Map.put(
      key,
      if value |> is_map and String.first(key) != "$" do
        value
        |> Map.put("binding", if(outer, do: "first", else: "last"))
        |> add_bindings(false)
      else
        value |> add_bindings()
      end
    )
  end)
end

def add_bindings(data, _), do: data

分配给 data 变量的示例数据:

data = %{
  "$include" => %{
    "hospitals" => %{
      "$include" => %{"rooms" => %{"beds" => %{}}},
      "$order" => %{"id" => "$asc"}
    },
    "doctors" => %{
      "$order" => %{"id" => "$desc"}
    }
  }
}

add_bindings函数调用:

data |> add_bindings()