Обновление отдельного значения в глубоко вложенной карте - PullRequest
0 голосов
/ 26 августа 2018

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

%{
  __meta__: #Ecto.Schema.Metadata<:loaded, "questions">,
  __struct__: MyApp.Question,
  active: true,
  description: "player points",
  id: 118,
  inserted_at: ~N[2018-08-26 19:48:22.501445],
  reserved: %Statcasters.Questions.Reserved{
    information: %{
      game_id: "b796cbe9-0bb6-4aaf-98b0-5da81c337208",
      player_id: "8ffb69ce-9a6b-44a6-8e8f-c069235d2d31",
      player_name: "Lebron James"
    },
    inputs: [%{label: "Player Points", type: "text"}]
  },
  type: "NBA",
  updated_at: ~N[2018-08-26 19:48:22.504193]
}

Как мне обновить reserved.information.player_id с 8ffb69ce-9a6b-44a6-8e8f-c069235d2d31 до 12345?

В Ruby это тривиальное изменение из-за изменчивости, ноУ меня проблемы с поиском лучшего способа обновить его в Elixir.

Текущая попытка (не работает)

Map.put(map, :player_id, "053600fb-3aae-422f-a9cb-9d102cca301f")

Это не работает, потому что просто добавляет player_id на первый уровенькарты.

Ответы [ 3 ]

0 голосов
/ 27 августа 2018

Как я могу обновить reserved.information.player_id с 8ffb69ce-9a6b-44a6-8e8f-c069235d2d31 до 12345?

defmodule Statcasters.Questions.Reserved do
  defstruct information: %{}, inputs: []
end

defmodule My do

  def go do
    map = %{
      __meta__: "hello world",
      __struct__: "boo hoo",
      active: true,
      description: "player points",
      id: 118,
      inserted_at: ~N[2018-08-26 19:48:22.501445],
      reserved: %Statcasters.Questions.Reserved{
        information: %{
          game_id: "b796cbe9-0bb6-4aaf-98b0-5da81c337208",
          player_id: "8ffb69ce-9a6b-44a6-8e8f-c069235d2d31",
          player_name: "Lebron James"
        },
        inputs: [%{label: "Player Points", type: "text"}]
      },
      type: "NBA",
      updated_at: ~N[2018-08-26 19:48:22.504193]
    }

    put_in(map.reserved.information.player_id, 12345)
  end


end

В iex:

~/elixir_programs$ iex
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]

Interactive Elixir (1.6.6) - press Ctrl+C to exit (type h() ENTER for help)

iex(1)> c "my.exs"
[My, Statcasters.Questions.Reserved]

iex(2)> My.go     
%{
  __meta__: "hello world",
  __struct__: "boo hoo",
  active: true,
  description: "player points",
  id: 118,
  inserted_at: ~N[2018-08-26 19:48:22.501445],
  reserved: %Statcasters.Questions.Reserved{
    information: %{
      game_id: "b796cbe9-0bb6-4aaf-98b0-5da81c337208",
      player_id: 12345,
      player_name: "Lebron James"
    },
    inputs: [%{label: "Player Points", type: "text"}]
  },
  type: "NBA",
  updated_at: ~N[2018-08-26 19:48:22.504193]
} 

iex(3)> 
0 голосов
/ 27 августа 2018

Предполагается, что ваша структура хранится в переменной с именем struct:

put_in(struct.reserved.information.player_id, "12345")
0 голосов
/ 27 августа 2018

Использование Kernel.put_in/3:

input = %{
  reserved: %{
    information: %{player_id: 42}
  }
}

put_in(input, ~w|reserved information player_id|a, -1)
#⇒ %{reserved: %{information: %{player_id: -1}}}

Если вы хотите изменить / отрегулировать значение вместо простого ввода нового, используйте Kernel.get_and_update_in/3. Чтобы последний работал с структурами , эта структура должна реализовывать поведение Access.

...