Добавление пары ключ-значение во вложенную карту динамически - PullRequest
0 голосов
/ 14 октября 2019

У меня есть эта карта:

           %{
             "$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) 

Любая помощь будет высоко ценится.

Спасибо

1 Ответ

2 голосов
/ 14 октября 2019

Вы можете выполнить итерацию карты с привязкой следующим образом (я заметил, что карты с $ не должны содержать привязку ключ):

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 = %{
  "$include" => %{
    "hospitals" => %{
      "$include" => %{"rooms" => %{"beds" => %{}}},
      "$order" => %{"id" => "$asc"}
    },
    "doctors" => %{
      "$order" => %{"id" => "$desc"}
    }
  }
}

и add_bindings вызов функции:

data |> add_bindings()
...