首页 > 解决方案 > 如果存在重复值,如何映射对象?

问题描述

我有两个列表,list_a = [%{id: 1, name: "Jack"}, %{id: 2, name: "John}]并且list_b = [%{id: nil, name: "Jack"}]

我想要实现的是通过比较两个列表,如果有重复的名称,则添加 field status: true,如果没有,则添加 field status: false

所以预期的结果是combined_list = [%{id: 1, name: "Jack", status: true}, %{id: 2, name: "John, status: false}]

为了实现目标,我循环了两个列表并合并了结果。

list_status_true =
for object <- list_a do
  found =      
    Enum.find(
      list_b,
        fn(x) ->
          x.name == object.name 
        end
      )

  if !is_nil(found) do
    %{
      id: object.id,
      name: object.name,
      status: true
    }
  end 
end

list_status_false =
for object <- list_b do
  found =      
    Enum.find(
      list_a,
        fn(x) ->
          x.name == object.name 
        end
      )

  if is_nil(found) do
    %{
      id: object.id,
      name: object.name,
      status: false
    }
  end 
end

list_status_true ++ list_status_false

但我认为这个功能可以简化..有什么建议吗?

标签: arraysloopselixir

解决方案


@Dogbert 提供的几乎相同的解决方案,但没有理解:

list_a = [%{id: 1, name: "Jack"}, %{id: 2, name: "John"}]
list_b = [%{id: nil, name: "Jack"}]

names = list_b |> Enum.map(& &1.name) |> Enum.uniq
Enum.map(list_a, fn %{name: name} = e ->
  Map.put(e, :status, name in names)
end)
#⇒ [%{id: 1, name: "Jack", status: true},
#   %{id: 2, name: "John", status: false}]

推荐阅读