List 从列表中筛选单个项目

List 从列表中筛选单个项目,list,filter,elixir,enumerable,List,Filter,Elixir,Enumerable,鉴于: 我可以做到: iex(9)> list_of_maps = [%{"a" => 1, "b" => 2, "c" => 3},%{"a" => 66, "b" => 1, "c" => 9},%{"a" => 66, "b" => 20, "c" => 8}] 然而,现在我害怕用每种语言写的部分来了——获取列表的第一个值来提取单个项目 elixir中是否有一些标准函数过滤列表,如果应用过滤器后只有一个项目,则返回单个项目

鉴于:

我可以做到:

iex(9)> list_of_maps = [%{"a" => 1, "b"  => 2, "c" => 3},%{"a" => 66, "b"  => 1, "c" => 9},%{"a" => 66, "b"  => 20, "c" => 8}]
然而,现在我害怕用每种语言写的部分来了——获取列表的第一个值来提取单个项目

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

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

只需将筛选出的列表导入/2的枚举中即可

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}]]
这将获得筛选列表的第一个元素,无论大小如何

此外,正如Dogbert在评论中提到的,您可以使用
Enum.find/2
而不是filter来查找第一个匹配项

first = list_of_maps |> Enum.filter(&(&1["a"] == 66)) |> Enum.at(0)

只需将筛选出的列表导入/2的枚举中即可

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}]]
这将获得筛选列表的第一个元素,无论大小如何

此外,正如Dogbert在评论中提到的,您可以使用
Enum.find/2
而不是filter来查找第一个匹配项

first = list_of_maps |> Enum.filter(&(&1["a"] == 66)) |> Enum.at(0)
elixir中是否有一些标准函数可以过滤列表,如果只有一个项目,则返回单个项目……或者如果有多个项目,则返回项目列表

没有,但模式匹配使它变得微不足道:

Enum.find(list_of_maps, &(&1["a"] == 66))
如果您想特别对待空列表(在“多”案例之前):

然后,函数调用链将是:

def single_or_many([]), do: :nil
elixir中是否有一些标准函数可以过滤列表,如果只有一个项目,则返回单个项目……或者如果有多个项目,则返回项目列表

没有,但模式匹配使它变得微不足道:

Enum.find(list_of_maps, &(&1["a"] == 66))
如果您想特别对待空列表(在“多”案例之前):

然后,函数调用链将是:

def single_or_many([]), do: :nil
从列表中查找一项 如果要筛选列表以仅获取一项,请使用:


获取一个或多个匹配项列表 要处理这两种情况,模式匹配是一种方法:

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
如果有多个匹配项,则返回列表;如果只有一个匹配项,则返回映射本身。

从列表中查找一项 如果要筛选列表以仅获取一项,请使用:


获取一个或多个匹配项列表 要处理这两种情况,模式匹配是一种方法:

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

如果有多个匹配项,它将返回一个列表;如果只有一个匹配项,它将返回映射本身。

FYI如果您只需要第一个匹配项,则有
Enum.find/2
。我很好奇您为什么需要它。这难道不需要添加一个特例来处理映射列表,并且只映射到从
filterr/2
获得结果后计划调用的任何函数吗?@Dogbert不确定我是否正确理解了这个问题,(将“地图列表和地图列表”解读为“地图列表和地图列表”-但在选择单个项目的情况下,似乎不需要特殊情况-这是预期的。但是,我现在可以看到,如果预期单个项目,使用
Enum.find/2
可以更清楚地显示对返回单个项目的预期。如果您只是想要第一个,有
Enum.find/2
。我很好奇你为什么需要这个。这难道不需要添加一个特例来处理映射列表,并且只映射到从
filter/2
获得结果后你计划调用的任何函数吗?@Dogbert不确定我是否正确理解了这个问题,(将“地图列表和地图列表”解读为“地图列表和地图列表”-但在选择单个项目的情况下,似乎不需要特殊情况-这是预期的。但是我现在可以看到,如果预期单个项目,使用
Enum.find/2
可以更清楚地显示对返回单个项目的预期。