Elixir/Phoenix 退出循环
Elixir/Phoenix exit the loop
我有两个带地图的列表:
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
?任何建议表示赞赏!
如果 O(n*m)
解决方案是可以接受的,那么就不需要写那么多代码了,并且存在新版本的标准只是 [=13= 中存在具有相同名称和不同版本的条目](这就是我认为你的代码所做的)。这可以只用一个 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
输出:
[%{name: "app1", new_version: true, version: "0.0.1"},
%{name: "app2", new_version: false, version: "0.0.1"}]
如果您需要运行大量应用程序和更新,您可能应该将更新转换为某种映射,以便内部逻辑执行得更快。
我有两个带地图的列表:
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
?任何建议表示赞赏!
如果 O(n*m)
解决方案是可以接受的,那么就不需要写那么多代码了,并且存在新版本的标准只是 [=13= 中存在具有相同名称和不同版本的条目](这就是我认为你的代码所做的)。这可以只用一个 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
输出:
[%{name: "app1", new_version: true, version: "0.0.1"},
%{name: "app2", new_version: false, version: "0.0.1"}]
如果您需要运行大量应用程序和更新,您可能应该将更新转换为某种映射,以便内部逻辑执行得更快。