Як перевірити, чи існує елемент у списку еліксирів або кортежі?


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?добре!
Денніс,

Відповіді:


125

Можна використовувати Enum.member?/2

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

За допомогою кортежу ви захочете перейти до списку, використовуючи спочатку Tuple.to_list/1

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

Дякую Газлер. Ваша відповідь правильна, але я хотів опублікувати окрему відповідь на основі всіх пропозицій, які я отримав від спільноти.
ewH

Зверніть увагу, що ви не зможете використовувати Enum.member?/2всередині охорони. У такому випадку вам доведеться покладатися in. Наприклад: def foo(string) when string in ["one", "two"], do: IO.puts(string). До речі, це смішно, адже inце макрос, що перекладається як Enum.member?/2: D
Алессандро

39

На основі відповідей тут та в Elixir Slack існує кілька способів перевірити, чи є якийсь елемент у списку. На відповідь @Gazler:

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

або просто

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

або

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

або якщо ви хочете знайти та повернути товар замість trueабоfalse

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

Ця відповідь схожа на єдину, яка відповідає на запитання ОП: "... існує в ЕЛІКСИРНОМУ СПИСКУ" ... а не в переліку.
Даніель Лізік

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]))

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.