从列表中过滤单个项目
Filter single item from a List
鉴于:
iex(9)> list_of_maps = [%{"a" => 1, "b" => 2, "c" => 3},%{"a" => 66, "b" => 1, "c" => 9},%{"a" => 66, "b" => 20, "c" => 8}]
我能做到:
iex(10)> Enum.filter(list_of_maps, &(&1["a"] == 1))
Enum.filter(list_of_maps, &(&1["a"] == 1))
[%{"a" => 1, "b" => 2, "c" => 3}]
但是现在我害怕用每种语言编写的部分 - 获取此列表的第一个值以提取单个项目。
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}]]
只需将筛选后的列表输入 Enum.at/2
first = list_of_maps |> Enum.filter(&(&1["a"] == 66)) |> Enum.at(0)
无论大小如何,这将获取筛选列表的第一个元素。
此外,正如 Dogbert 在评论中提到的,您可以只使用 Enum.find/2
而不是过滤器来找到第一个匹配项。
Enum.find(list_of_maps, &(&1["a"] == 66))
Is there some standard function in elixir that filters a list, returning single item if there is only one item … or a list of items if there are numerous items
不,但是模式匹配让它变得微不足道:
def single_or_many([single]), do: single
def single_or_many(many), do: many
如果您想特殊处理空列表(在 'many' 案例之前):
def single_or_many([]), do: :nil
那么函数调用链为:
list_of_maps
|> Enum.filter(&(&1["a"] == 1))
|> single_or_many
从列表中查找一项
如果要过滤列表以仅获取一项,请使用Enum.find/2
:
Enum.find(list_of_maps, fn m -> m["a"] == 1 end)
获取一个或一系列匹配项
要处理这两种情况,模式匹配是可行的方法:
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
然后你可以像这样使用它:
MyEnum.filter(list_of_maps, &(&1["a"] == 1))
如果有多个匹配项,它会return一个列表;如果只有一个匹配项,它会return一个地图本身。
鉴于:
iex(9)> list_of_maps = [%{"a" => 1, "b" => 2, "c" => 3},%{"a" => 66, "b" => 1, "c" => 9},%{"a" => 66, "b" => 20, "c" => 8}]
我能做到:
iex(10)> Enum.filter(list_of_maps, &(&1["a"] == 1))
Enum.filter(list_of_maps, &(&1["a"] == 1))
[%{"a" => 1, "b" => 2, "c" => 3}]
但是现在我害怕用每种语言编写的部分 - 获取此列表的第一个值以提取单个项目。
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}]]
只需将筛选后的列表输入 Enum.at/2
first = list_of_maps |> Enum.filter(&(&1["a"] == 66)) |> Enum.at(0)
无论大小如何,这将获取筛选列表的第一个元素。
此外,正如 Dogbert 在评论中提到的,您可以只使用 Enum.find/2
而不是过滤器来找到第一个匹配项。
Enum.find(list_of_maps, &(&1["a"] == 66))
Is there some standard function in elixir that filters a list, returning single item if there is only one item … or a list of items if there are numerous items
不,但是模式匹配让它变得微不足道:
def single_or_many([single]), do: single
def single_or_many(many), do: many
如果您想特殊处理空列表(在 'many' 案例之前):
def single_or_many([]), do: :nil
那么函数调用链为:
list_of_maps
|> Enum.filter(&(&1["a"] == 1))
|> single_or_many
从列表中查找一项
如果要过滤列表以仅获取一项,请使用Enum.find/2
:
Enum.find(list_of_maps, fn m -> m["a"] == 1 end)
获取一个或一系列匹配项
要处理这两种情况,模式匹配是可行的方法:
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
然后你可以像这样使用它:
MyEnum.filter(list_of_maps, &(&1["a"] == 1))
如果有多个匹配项,它会return一个列表;如果只有一个匹配项,它会return一个地图本身。