我有两个列表,list_a = [%{id: 1, name: "Jack"}, %{id: 2, name: "John}]
和list_b = [%{id: nil, name: "Jack"}]
我想要实现的是,通过比较两个列表,如果有重复的名称,请添加字段status: true
,如果没有,请添加字段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
但我觉得这个功能可以简化..有什么建议吗?
答案 0 :(得分:2)
我将所有姓名收集到MapSet
中,然后循环浏览list_b
一次,检查MapSet
中是否存在该名称:
list_a = [%{id: 1, name: "Jack"}, %{id: 2, name: "John"}]
list_b = [%{id: nil, name: "Jack"}]
names = for x <- list_b, into: MapSet.new, do: x.name
IO.inspect for x <- list_a, do: Map.put(x, :status, x.name in names)
输出:
[%{id: 1, name: "Jack", status: true}, %{id: 2, name: "John", status: false}]
答案 1 :(得分:2)
与@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}]