我有两张地图列表:
apps = [%{name: "app1", version: "0.0.1"}, %{name: "app2", version: "0.0.1"}]
updates_list = [%{name: "app1", version: "0.0.2"},
%{name: "app2", version: "0.0.1"},
%{name: "app3", version: "0.0.1"},
%{name: "app4", version: "0.0.1"}]
并需要枚举updates_list
,将新密钥放入apps
列表中的每个元素,以显示是否有更新。即此处有app1
的新版本,我需要添加new_version: true/false
并获得所需的结果:
result = [%{name: "app1", version: "0.0.1", new_version: true},
%{name: "app2", version: "0.0.1", new_version: false}]
我尝试过以下功能:
updates_map = Enum.map(updates_list, fn (x) -> Map.put(%{}, x.name, x.version ) end)
result = Enum.map(apps, fn (x) -> map_updates(x, updates_map) end)
和功能:
defp map_updates(app, updates_map) do
app_map = Map.from_struct(app)
for update <- updates_map do
if Map.has_key?(update, app_map.name) do
if Map.fetch(update, app_map.name) != app_map.version do
app_map = app_map |> Map.put(:new_version, true)
else
app_map = app_map |> Map.put(:new_version, false)
end
else
app_map = app_map
end
end
app_map
end
但是因为它通过所有updates_map
枚举每个应用程序,它只是覆盖它,我没有得到任何结果。如何退出循环,或保留更改以实现上述result
?任何建议表示赞赏!
答案 0 :(得分:2)
如果O(n*m)
解决方案是可接受的,并且存在新版本的条件只是{{1}中存在具有相同名称和不同版本的条目,则无需编写如此多的代码1}}(这是我认为你的代码所做的)。只需一个update_map
和一个嵌套for
:
Enum.any?
输出:
apps = [%{name: "app1", version: "0.0.1"}, %{name: "app2", version: "0.0.1"}]
updates_map = [%{name: "app1", version: "0.0.2"},
%{name: "app2", version: "0.0.1"},
%{name: "app4", version: "0.0.1"},
%{name: "app4", version: "0.0.1"}]
updated_apps = for app <- apps do
new_version = Enum.any?(updates_map, fn update ->
app.name == update.name && app.version != update.version
end)
Map.put(app, :new_version, new_version)
end
IO.inspect updated_apps
如果您需要在大量应用程序和更新上运行,您应该将更新转换为某种类型的Map,以便内部逻辑执行得更快。