1

I have this struct:

%MyApp.ScoreTable{
  __meta__: #Ecto.Schema.Metadata<:loaded, "score_tables">,
  id: "7f320636-2176-4af2-9207-6251416dd6c2",
  inserted_at: ~N[2018-11-04 21:08:26.024733],
  question: #Ecto.Association.NotLoaded<association :question is not loaded>,
  question_id: "dadc6e57-49f4-4339-9c0f-d40dbc6df534",
  season: #Ecto.Association.NotLoaded<association :season is not loaded>,
  season_id: "c356bae0-bee8-45df-b035-dc117908bebd",
  table_details: %MyApp.TableDetails{
    information: [
      %{
        "team_id" => "7ca4c7ac-850b-4f27-8b6e-1feeb1e0629b",
        "team_score" => "N/A"
      },
      %{"team_id" => "f78c069d-1500-4cfe-a201-13223c417f82", "team_score" => 5},
      %{"team_id" => "4b3459a0-f81c-436d-a68c-3a00dea62a2d", "team_score" => 5},
      %{"team_id" => "9dff5653-dee4-4fef-9d91-7d53f3861275", "team_score" => 10},
      %{"team_id" => "dab53fe6-419b-4a86-a1c6-9c1f65445e12", "team_score" => 15}
    ]
  },
  updated_at: ~N[2018-11-04 21:08:26.024739]
}

And I want to replace fully the table_details.information list with this one:

[
  %{
    "team_id" => "cebda2b5-26e1-4804-8529-17367155db06",
    "team_place" => 1,
    "team_score" => 5
  },
  %{
    "team_id" => "ea800d1c-a079-4f6f-9a91-2a085779dfa9",
    "team_place" => 1,
    "team_score" => 5
  },
  %{
    "team_id" => "2d9253fa-63b7-45dd-bf8f-370598a1424c",
    "team_place" => 3,
    "team_score" => 10
  },
  %{
    "team_id" => "1748f471-08ae-49ed-844b-0fe1bc539a8f",
    "team_place" => 4,
    "team_score" => 15
  },
  %{
    "team_id" => "df2f5102-4e6f-4480-8167-ebe0548cd4ba",
    "team_place" => 5,
    "team_score" => "N/A"
  }
]

To be clear, I want to wholesale swap the old list with the new list of maps. How can I achieve this?

1 Answer 1

2

You can use the struct update syntax. Assuming your whole datastructure is stored in data and the new list in new_information, something like this will work:

data = %{data | table_details: %{data.table_details | information: new_information}}

Note that the update syntax creates a new version of the structure, so you need to assign it to a variable or return it from your function as appropriate.

Sometimes it's more clear what you're trying to achieve if you use Access with the associated Kernel macros. In this case:

data = put_in(data, [Access.key(:table_details), Access.key(:information)], new_information)

This basically does the same thing, but you only need to specify the path to the change and what to change. In the previous example one might make a mistake like %{other_data.table_details | information: new_information} (note other_data instead of data), in this case it's easy to see at a glance that only that one part of the structure is modified.

Sign up to request clarification or add additional context in comments.

1 Comment

That is some awesome information. Thanks for the help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.