使用 Enum.reduce 过滤地图列表

Filter list of map using Enum.reduce

我有一张地图

%Subject
{
    sub_id: 1,
    content: %{
               sub_name: "oracle",
               type: "code",
    },
    publisher: "quantum",
    ouby_id: "afc5a6e23208",
    region: "USA",
  }

我有一个列表如下

[
%user{id: 4, name: "kane", status: "A"},
%user{id: 3, name: "Harry", status: "P"},
%user{id: 5, name: "Tom", status: "A"}
]

我想过滤状态为“A”的用户并创建一个新地图

[
%{id: 4,name: "kane", sub_id: 1, sub_name: "oracle"},
%{id: 5,name: "Tom", sub_id: 1, sub_name: "oracle"}
]

谁能帮我解决这个问题?

谢谢。

我认为在这里使用 filtermap 的组合会更好。你没有解释为什么 Subject 是必要的,所以我只是硬编码你说的值总是一样的。

[
  %User{id: 4, name: "kane", status: "A"},
  %User{id: 3, name: "Harry", status: "P"},
  %User{id: 5, name: "Tom", status: "A"}
]
|> Stream.filter(&(&1.status == "A"))
|> Enum.map(fn map ->
  %{
    id: map.id,
    name: map.name,
    sub_id: 1,
    sub_name: "oracle"
  }
end)

结果:

[
  %{id: 4, name: "kane", sub_id: 1, sub_name: "oracle"},
  %{id: 3, name: "Harry", sub_id: 1, sub_name: "oracle"},
  %{id: 5, name: "Tom", sub_id: 1, sub_name: "oracle"}
]

尽管 Adam 的解决方案完全正确,但我最好选择 Enum.reduce/3

[
  %{id: 4, name: "kane", status: "A"},
  %{id: 3, name: "Harry", status: "P"},
  %{id: 5, name: "Tom", status: "A"}
]
|> Enum.reduce([], fn
  %{status: "A"} = elem, acc ->
    elem =
      elem
      |> Map.take(~w|id name|a)
      |> Map.put(:sub_id, subject.sub_id),
      |> Map.put(:sub_name, subject.content.sub_name)
    [elem | acc]
  _, acc ->
    acc
end)
|> Enum.reverse()