如何检查Elixir列表或元组中是否存在某个项目?


83

这看似简单,但我似乎无法在文档中找到它。我需要简单地返回,true或者false如果列表或元组中存在某个项目。是Enum.find/3真正做到这一点的最好方法是什么?

Enum.find(["foo", "bar"], &(&1 == "foo")) != nil

2
对于列表,我可以看到您想在哪里查看该项目是否在其中Enum.member?/ 2会很好。但是对于一个元组,您通常关心值的位置,这是元组的优点之一……如果您不关心位置,则可能要考虑使用元组
CaptChrisD

如果正确,您可能需要将@Gazler的答案标记为已接受的答案。
Onorio Catenacci

1
关于性能的快速说明。该x in y后卫非常出色,因为它在编译时会创建不同的函数定义。在运行时,它的性能较差,相当于Enum.member?,尽管它们适合用于较小的n。对于较大的n循环和紧密循环,您可以从诸如的哈希值中获得更好的性能MapSet.member?。但在大多数情况下,x in y并且Enum.member?都很好!
丹尼斯,

Answers:


125

您可以使用 Enum.member?/2

Enum.member?(["foo", "bar"], "foo")
# true

使用元组时,您首先需要使用转换为列表 Tuple.to_list/1

Tuple.to_list({"foo", "bar"})
# ["foo", "bar"]

谢谢瞪羚。您的答案是正确的,但是我想根据我在社区中收到的所有建议发布单独的答案。
ewH 2016年

请注意,您将无法Enum.member?/2在防护罩内使用。在这种情况下,您将不得不依靠in。例如:def foo(string) when string in ["one", "two"], do: IO.puts(string)。顺便说一句,这很有趣,因为in有一个宏可以转换为Enum.member?/2:D
Alessandro

39

根据此处和Elixir Slack中的答案,有多种方法可以检查列表中是否存在某项。@Gazler的每个答案:

Enum.member?(["foo", "bar"], "foo")
# true

或简单地

"foo" in ["foo", "bar"]
# true

要么

Enum.any?(["foo", "bar"], &(&1 == "foo")
# true

或者,如果您想查找并退回该商品,而不是truefalse

Enum.find(["foo", "bar"], &(&1 == "foo")
# "foo"

如果要检查元组,则需要转换为列表(信誉@Gazler):

Tuple.to_list({"foo", "bar"})
# ["foo", "bar"]

但是,正如@CaptChrisD在评论中指出的那样,这对元组并不常见,因为人们通常关心项目在元组中用于模式匹配的确切位置。


26

或者只是使用in

iex(1)> "foo" in ["foo", "bar"]
true
iex(2)> "foo" in Tuple.to_list({"foo", "bar"})
true

这个答案就像回答OP问题的唯一答案:“ ...存在于长生不老药列表中” ...不是枚举。
Daniel Lizik

2

我昨天开始使用Elixir进行编程,但是我将尝试在JS中做过的很多事情,当列表中包含很多元素并且您不想一直使用Enum.member遍历时,这可能会很有用?

map_existence = Enum.reduce(list,%{}, &(Map.put(&2,&1,true)))
map_existence[item_to_check]

您还可以检索与其他列表的交集:

Enum.filter(some_other_list,&(map_existence[&1]))

1

您也可以使用Enum.find_value/3

iex(1)> Enum.find_value(["foo", "bar"],false, fn(x)-> x=="foo" end)
true

iex(2)> Enum.find_value(["foo", "bar"],false, fn(x)-> x=="food" end)
false
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.