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"}]

如果您需要运行大量应用程序和更新,您可能应该将更新转换为某种映射,以便内部逻辑执行得更快。