从列表中过滤单个项目

cat*_*ory 1 list filter enumerable elixir

鉴于:

iex(9)> list_of_maps = [%{"a" => 1, "b"  => 2, "c" => 3},%{"a" => 66, "b"  => 1, "c" => 9},%{"a" => 66, "b"  => 20, "c" => 8}]
Run Code Online (Sandbox Code Playgroud)

我可以:

iex(10)> Enum.filter(list_of_maps, &(&1["a"] == 1))                                                                                                                                                                
Enum.filter(list_of_maps, &(&1["a"] == 1))                                                                                                                                                                         
[%{"a" => 1, "b" => 2, "c" => 3}]
Run Code Online (Sandbox Code Playgroud)

但是现在到了我害怕用每种语言编写的部分 - 获取此列表的第一个值以提取单个项目。

elixir 中是否有一些标准函数可以过滤列表,如果应用过滤器后只有一个项目,则返回单个项目,或者如果应用过滤器后返回多个项目,则返回项目列表?喜欢:

iex(11)> Enum.filterr(list_of_maps, &(&1["a"] == 1))                                                                                                                                                                
Enum.filter(list_of_maps, &(&1["a"] == 1))                                                                                                                                                                         
%{"a" => 1, "b" => 2, "c" => 3}

iex(12)> Enum.filterr(list_of_maps, &(&1["a"] == 66))                                                                                                                                                                
Enum.filter(list_of_maps, &(&1["a"] == 66))                                                                                                                                                                         
[%{"a" => 66, "b"  => 1, "c" => 9},%{"a" => 66, "b"  => 20, "c" => 8}]]
Run Code Online (Sandbox Code Playgroud)

She*_*yar 5

从列表中查找一项

如果要过滤列表以仅获取一项,请使用Enum.find/2

Enum.find(list_of_maps, fn m -> m["a"] == 1 end)
Run Code Online (Sandbox Code Playgroud)

获取一个或一组匹配项

要处理这两种情况,模式匹配是要走的路:

defmodule MyEnum do
  def filter(list, fun) do
    list
    |> Enum.filter(fun)
    |> normalize
  end

  defp normalize([item]), do: item
  defp normalize(list),   do: list
end
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样使用它:

MyEnum.filter(list_of_maps, &(&1["a"] == 1))
Run Code Online (Sandbox Code Playgroud)

如果有多个匹配项,它将返回一个列表,如果只有一个匹配项,则返回地图本身。