我有这个结构:
%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]
}
我想用此列表完全替换table_details.information
列表:
[
%{
"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"
}
]
为清楚起见,我想将旧列表与新的地图列表完全交换。我该如何实现?
答案 0 :(得分:2)
您可以使用struct update语法。假设您的整个数据结构存储在data
中,新列表存储在new_information
中,则这样的方法将起作用:
data = %{data | table_details: %{data.table_details | information: new_information}}
请注意,更新语法会创建该结构的新版本,因此您需要将其分配给变量或从函数中适当地返回它。
有时,如果将Access与关联的Kernel宏一起使用,您会尝试实现什么。在这种情况下:
data = put_in(data, [Access.key(:table_details), Access.key(:information)], new_information)
这基本上可以完成相同的操作,但是您只需要指定更改的路径和更改内容即可。在前面的示例中,可能会犯诸如%{other_data.table_details | information: new_information}
之类的错误(请注意,other_data
而非data
),在这种情况下,一眼就可以看出,只有结构的一部分修改。