Skip to content

Commit

Permalink
Enum.split_with -> Enum.split_while
Browse files Browse the repository at this point in the history
  • Loading branch information
José Valim committed Sep 15, 2012
1 parent 1fd9ab6 commit 20f1115
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 32 deletions.
34 changes: 20 additions & 14 deletions lib/elixir/lib/enum.ex
Expand Up @@ -56,7 +56,7 @@ defprotocol Enum.OrdIterator do
@moduledoc """
This protocol is invoked by some functions in Enum which
requires an ordered collection to function correctly. For
instance, `Enum.split_with/2`, `Enum.take_while` all rely
instance, `Enum.split_while/2`, `Enum.take_while` all rely
on this protocol.
An ordered collection does not mean the items are ordered
Expand Down Expand Up @@ -716,26 +716,32 @@ defmodule Enum do
split(list, real_count)
end

@doc false
def split_with(collection, fun) do
IO.write "[WARNING] Enum.split_with is deprecated, please use split_while instead\n#{Exception.formatted_stacktrace}"
split_while(collection, fun)
end

@doc """
Splits `collection` at the first element, for which `fun` returns true.
Expects an ordered collection.
## Examples
Enum.split_with [1,2,3,4], fn x -> x == 2 end
Enum.split_while [1,2,3,4], fn x -> x == 2 end
#=> { [1], [2, 3, 4] }
"""
def split_with(collection, fun) when is_list(collection) do
do_split_with(collection, fun, [])
def split_while(collection, fun) when is_list(collection) do
do_split_while(collection, fun, [])
end

def split_with(collection, fun) do
def split_while(collection, fun) do
case O.iterator(collection) do
{ iterator, pointer } ->
module = O.__impl_for__!(collection)
do_split_with(pointer, iterator, fun, [], module)
do_split_while(pointer, iterator, fun, [], module)
list when is_list(list) ->
do_split_with(list, fun, [])
do_split_while(list, fun, [])
end
end

Expand Down Expand Up @@ -1049,29 +1055,29 @@ defmodule Enum do
acc
end

## split_with
## split_while

defp do_split_with([h|t], fun, acc) do
defp do_split_while([h|t], fun, acc) do
if fun.(h) do
do_split_with(t, fun, [h|acc])
do_split_while(t, fun, [h|acc])
else
{ :lists.reverse(acc), [h|t] }
end
end

defp do_split_with([], _, acc) do
defp do_split_while([], _, acc) do
{ :lists.reverse(acc), [] }
end

defp do_split_with({ h, next } = extra, iterator, fun, acc, module) do
defp do_split_while({ h, next } = extra, iterator, fun, acc, module) do
if fun.(h) do
do_split_with(iterator.(next), iterator, fun, [h|acc], module)
do_split_while(iterator.(next), iterator, fun, [h|acc], module)
else
{ :lists.reverse(acc), module.to_list(extra, iterator) }
end
end

defp do_split_with(:stop, _, _, acc, _module) do
defp do_split_while(:stop, _, _, acc, _module) do
{ :lists.reverse(acc), [] }
end

Expand Down
36 changes: 18 additions & 18 deletions lib/elixir/test/elixir/enum_test.exs
Expand Up @@ -206,13 +206,13 @@ defmodule EnumTest.List do
assert Enum.split([1,2,3], -10) == { [], [1,2,3] }
end

test :split_with do
assert Enum.split_with([1,2,3], fn(_) -> false end) == { [], [1,2,3] }
assert Enum.split_with([1,2,3], fn(_) -> true end) == { [1,2,3], [] }
assert Enum.split_with([1,2,3], fn(x) -> x > 2 end) == { [], [1,2,3] }
assert Enum.split_with([1,2,3], fn(x) -> x > 3 end) == { [], [1,2,3] }
assert Enum.split_with([1,2,3], fn(x) -> x < 3 end) == { [1,2], [3] }
assert Enum.split_with([], fn(_) -> true end) == { [], [] }
test :split_while do
assert Enum.split_while([1,2,3], fn(_) -> false end) == { [], [1,2,3] }
assert Enum.split_while([1,2,3], fn(_) -> true end) == { [1,2,3], [] }
assert Enum.split_while([1,2,3], fn(x) -> x > 2 end) == { [], [1,2,3] }
assert Enum.split_while([1,2,3], fn(x) -> x > 3 end) == { [], [1,2,3] }
assert Enum.split_while([1,2,3], fn(x) -> x < 3 end) == { [1,2], [3] }
assert Enum.split_while([], fn(_) -> true end) == { [], [] }
end

test :take do
Expand Down Expand Up @@ -401,9 +401,9 @@ defmodule EnumTest.HashDict do
end
end

test :split_with do
test :split_while do
assert_raise Protocol.UndefinedError, fn ->
Enum.split_with HashDict.new, fn(x) -> x end
Enum.split_while HashDict.new, fn(x) -> x end
end
end

Expand Down Expand Up @@ -455,9 +455,9 @@ defmodule EnumTest.Orddict do
assert Enum.split(dict, -10) == { [], [a: 1, c: 3, b: 2] }
end

test :split_with do
test :split_while do
dict = Orddict.new [a: 1, b: 3, c: 2, d: 4]
assert Enum.split_with(dict, fn({_k, v}) -> rem(v, 2) == 1 end) == { [a: 1, b: 3], [c: 2, d: 4] }
assert Enum.split_while(dict, fn({_k, v}) -> rem(v, 2) == 1 end) == { [a: 1, b: 3], [c: 2, d: 4] }
end

test :take do
Expand Down Expand Up @@ -696,16 +696,16 @@ defmodule EnumTest.Range do
assert Enum.split(range, 3) == { [], [] }
end

test :split_with do
test :split_while do
range = Range.new(first: 1, last: 3)
assert Enum.split_with(range, fn(_) -> false end) == { [], [1,2,3] }
assert Enum.split_with(range, fn(_) -> true end) == { [1,2,3], [] }
assert Enum.split_with(range, fn(x) -> x > 2 end) == { [], [1,2,3] }
assert Enum.split_with(range, fn(x) -> x > 3 end) == { [], [1,2,3] }
assert Enum.split_with(range, fn(x) -> x < 3 end) == { [1,2], [3] }
assert Enum.split_while(range, fn(_) -> false end) == { [], [1,2,3] }
assert Enum.split_while(range, fn(_) -> true end) == { [1,2,3], [] }
assert Enum.split_while(range, fn(x) -> x > 2 end) == { [], [1,2,3] }
assert Enum.split_while(range, fn(x) -> x > 3 end) == { [], [1,2,3] }
assert Enum.split_while(range, fn(x) -> x < 3 end) == { [1,2], [3] }

range = Range.new(first: 1, last: 0)
assert Enum.split_with(range, fn(_) -> true end) == { [], [] }
assert Enum.split_while(range, fn(_) -> true end) == { [], [] }
end

test :take do
Expand Down

0 comments on commit 20f1115

Please sign in to comment.