diff --git a/lib/elixir/lib/enum.ex b/lib/elixir/lib/enum.ex index da5a95eda8..f838efd3f1 100644 --- a/lib/elixir/lib/enum.ex +++ b/lib/elixir/lib/enum.ex @@ -759,6 +759,28 @@ defmodule Enum do end end + @doc """ + Checks if the given `term` is included in the `collection`. + + ## Examples + + iex> Enum.member?(1 .. 3, 1) + true + iex> Enum.member?([1, 2, 3, 4], 10) + false + + """ + @spec member?(t, term) :: boolean + def member?(collection, term) do + case I.iterator(collection) do + { iterator, pointer } -> + do_member?(pointer, iterator, term) + + list when is_list(list) -> + List.member?(list, term) + end + end + @doc """ Partitions `collection` into two where the first one contains elements for which `fun` returns a truthy value, and the second one -- for which `fun` @@ -1549,6 +1571,20 @@ defmodule Enum do { :lists.reverse(list_acc), acc } end + ## member? + + def do_member?(:stop, _, _) do + false + end + + def do_member?({ h, _ }, _, term) when h == term do + true + end + + def do_member?({ h, next }, iterator, term) do + do_member?(iterator.(next), iterator, term) + end + ## partition defp do_partition([h|t], fun, acc1, acc2) do diff --git a/lib/elixir/test/elixir/enum_test.exs b/lib/elixir/test/elixir/enum_test.exs index 695de5e5ff..ebfd9e183d 100644 --- a/lib/elixir/test/elixir/enum_test.exs +++ b/lib/elixir/test/elixir/enum_test.exs @@ -182,6 +182,12 @@ defmodule EnumTest.List do assert Enum.map_reduce([1,2,3], 1, fn(x, acc) -> { x * 2, x + acc } end) == { [2,4,6], 7 } end + test :member? do + refute Enum.member?([], 0) + assert Enum.member?([1, 2, 3], 2) + assert Enum.member?(1 .. 3, 1) + end + test :partition do assert Enum.partition([1,2,3], fn(x) -> rem(x, 2) == 0 end) == { [2], [1,3] } assert Enum.partition([2,4,6], fn(x) -> rem(x, 2) == 0 end) == { [2,4,6], [] }