Skip to content

Commit cd18fc7

Browse files
committed
Remove Enum.zip_reduce_while, as it is equivalent to Stream.zip+Enum.reduce_while
1 parent 6d39898 commit cd18fc7

File tree

2 files changed

+18
-169
lines changed

2 files changed

+18
-169
lines changed

lib/elixir/lib/enum.ex

Lines changed: 18 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -3447,7 +3447,7 @@ defmodule Enum do
34473447
def zip([]), do: []
34483448

34493449
def zip(enumerables) do
3450-
zip_reduce_while(enumerables, [], &{:cont, [List.to_tuple(&1) | &2]})
3450+
zip_reduce(enumerables, [], &[List.to_tuple(&1) | &2])
34513451
|> :lists.reverse()
34523452
end
34533453

@@ -3497,9 +3497,7 @@ defmodule Enum do
34973497
end
34983498

34993499
def zip_with(enumerable1, enumerable2, zip_fun) when is_function(zip_fun, 2) do
3500-
reducer = fn l, r, acc -> {:cont, [zip_fun.(l, r) | acc]} end
3501-
3502-
zip_reduce_while(enumerable1, enumerable2, [], reducer)
3500+
zip_reduce(enumerable1, enumerable2, [], fn l, r, acc -> [zip_fun.(l, r) | acc] end)
35033501
|> :lists.reverse()
35043502
end
35053503

@@ -3529,15 +3527,19 @@ defmodule Enum do
35293527
def zip_with([], _fun), do: []
35303528

35313529
def zip_with(enumerables, zip_fun) do
3532-
reducer = fn values, acc -> {:cont, [zip_fun.(values) | acc]} end
3533-
3534-
zip_reduce_while(enumerables, [], reducer)
3530+
zip_reduce(enumerables, [], fn values, acc -> [zip_fun.(values) | acc] end)
35353531
|> :lists.reverse()
35363532
end
35373533

35383534
@doc """
35393535
Reduces over two enumerables halting as soon as either enumerable is empty.
35403536
3537+
In practice, the behaviour provided by this function can be achieved with:
3538+
3539+
Enum.reduce(Stream.zip(left, right), acc, reducer)
3540+
3541+
But `zip_reduce/4` exists for convenience purposes.
3542+
35413543
## Examples
35423544
35433545
iex> Enum.zip_reduce([1, 2], [3, 4], 0, fn x, y, acc -> x + y + acc end)
@@ -3555,8 +3557,8 @@ defmodule Enum do
35553557
end
35563558

35573559
def zip_reduce(left, right, acc, reducer) when is_function(reducer, 3) do
3558-
non_stop_reducer = &{:cont, reducer.(&1, &2, &3)}
3559-
zip_reduce_while(left, right, acc, non_stop_reducer)
3560+
reduce = fn [l, r], acc -> {:cont, reducer.(l, r, acc)} end
3561+
Stream.zip_with([left, right], & &1).({:cont, acc}, reduce) |> elem(1)
35603562
end
35613563

35623564
@doc """
@@ -3565,6 +3567,12 @@ defmodule Enum do
35653567
The reducer will receive 2 args, a list of elements (one from each enum) and the
35663568
accumulator.
35673569
3570+
In practice, the behaviour provided by this function can be achieved with:
3571+
3572+
Enum.reduce(Stream.zip(enums), acc, reducer)
3573+
3574+
But `zip_reduce/4` exists for convenience purposes.
3575+
35683576
## Examples
35693577
35703578
iex> enums = [[1, 1], [2, 2], [3, 3]]
@@ -3584,80 +3592,7 @@ defmodule Enum do
35843592
def zip_reduce([], acc, reducer) when is_function(reducer, 2), do: acc
35853593

35863594
def zip_reduce(enums, acc, reducer) when is_function(reducer, 2) do
3587-
non_stop_reducer = &{:cont, reducer.(&1, &2)}
3588-
zip_reduce_while(enums, acc, non_stop_reducer)
3589-
end
3590-
3591-
@doc """
3592-
Reduces over two enumerables halting if the accumulator returns
3593-
`{:halt, value}` or if either of the enumerables is empty.
3594-
3595-
The reducer will receive 3 args, the left enumerable's element,
3596-
the right enumberable's element and the accumulator. It should
3597-
return one of:
3598-
3599-
* `{:halt, value}` - This will halt the reduction and return `value`
3600-
* `{:cont, value}` - This will continue with the next step of the reduction
3601-
3602-
## Examples
3603-
3604-
iex> reducer = fn left, right, acc -> {:cont, [left + right | acc ]} end
3605-
...> Enum.zip_reduce_while([1], [2], [], reducer)
3606-
[3]
3607-
3608-
iex> Enum.zip_reduce_while([1, 2], [2, 2], [], fn left, right, acc ->
3609-
...> if left <= 1, do: {:cont, [left + right | acc]}, else: {:halt, acc}
3610-
...> end)
3611-
[3]
3612-
3613-
"""
3614-
@doc since: "1.12.0"
3615-
@spec zip_reduce_while(t, t, acc, (enum1_elem :: term, enum2_elem :: term, acc -> acc)) ::
3616-
{:cont | :halt, acc}
3617-
when acc: term
3618-
def zip_reduce_while(left, right, acc, reducer)
3619-
when is_list(left) and is_list(right) and is_function(reducer, 3) do
3620-
zip_reduce_while_list(left, right, {:cont, acc}, reducer)
3621-
end
3622-
3623-
def zip_reduce_while(left, right, acc, reducer) when is_function(reducer, 3) do
3624-
reduce = fn [l, r], acc -> reducer.(l, r, acc) end
3625-
Stream.zip_with([left, right], & &1).({:cont, acc}, reduce) |> elem(1)
3626-
end
3627-
3628-
@doc """
3629-
Reduces over all enumerables halting if the accumulator returns
3630-
`{:halt, value}` or if any of the enumerables is empty.
3631-
3632-
The reducer will receive 2 args, a list of the yielded elements
3633-
and the accumulator. It should return one of:
3634-
3635-
* `{:halt, value}` - This will halt the reduction and return `value`
3636-
* `{:cont, value}` - This will continue with the next step of the reduction
3637-
3638-
## Examples
3639-
3640-
iex> enums = [[1, 2],[3, 4]]
3641-
...> reducer = fn values, acc -> {:cont, Enum.sum(values) + acc} end
3642-
...> Enum.zip_reduce_while(enums, 0, reducer)
3643-
10
3644-
3645-
iex> enums = [[1, 2],[3, 4]]
3646-
...> reducer = fn values, acc -> {:suspend, [Enum.sum(values) | acc]} end
3647-
...> Enum.zip_reduce_while(enums, [], reducer)
3648-
[4]
3649-
3650-
iex> enums = [[1, 2],[3, 4]]
3651-
...> reducer = fn values, acc -> {:halt, [Enum.sum(values) | acc]} end
3652-
...> Enum.zip_reduce_while(enums, [], reducer)
3653-
[4]
3654-
"""
3655-
@doc since: "1.12.0"
3656-
@spec zip_reduce_while([t], acc, ([term], acc -> acc)) :: {:cont | :halt, acc} when acc: term
3657-
def zip_reduce_while([], acc, reducer) when is_function(reducer, 2), do: acc
3658-
3659-
def zip_reduce_while(enums, acc, reducer) when is_function(reducer, 2) do
3660-
Stream.zip_with(enums, & &1).({:cont, acc}, reducer) |> elem(1)
3595+
Stream.zip_with(enums, & &1).({:cont, acc}, &{:cont, reducer.(&1, &2)}) |> elem(1)
36613596
end
36623597

36633598
## Helpers
@@ -4281,14 +4216,6 @@ defmodule Enum do
42814216

42824217
defp zip_reduce_list(_, [], acc, _fun), do: acc
42834218
defp zip_reduce_list([], _, acc, _fun), do: acc
4284-
4285-
defp zip_reduce_while_list(_left, _right, {:halt, acc}, _), do: acc
4286-
defp zip_reduce_while_list([], _right, {:cont, acc}, _), do: acc
4287-
defp zip_reduce_while_list(_left, [], {:cont, acc}, _), do: acc
4288-
4289-
defp zip_reduce_while_list([l_head | l_tail], [r_head | r_tail], {:cont, acc}, reducer) do
4290-
zip_reduce_while_list(l_tail, r_tail, reducer.(l_head, r_head, acc), reducer)
4291-
end
42924219
end
42934220

42944221
defimpl Enumerable, for: List do

lib/elixir/test/elixir/enum_test.exs

Lines changed: 0 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -62,84 +62,6 @@ defmodule EnumTest do
6262
end
6363
end
6464

65-
describe "zip_reduce_while/4" do
66-
test "lists" do
67-
left = [1, 2]
68-
right = [3, 4]
69-
reducer = fn x, y, acc -> {:cont, x + y + acc} end
70-
assert Enum.zip_reduce_while(left, right, 0, reducer) == 10
71-
72-
left = [1, 2]
73-
right = [3, 4]
74-
reducer = fn x, y, acc -> {:cont, [x + y | acc]} end
75-
assert Enum.zip_reduce_while(left, right, [], reducer) == [6, 4]
76-
77-
# Halting the reduction
78-
left = [1, 2]
79-
right = [3, 4]
80-
reducer = fn x, y, acc -> {:halt, [x + y | acc]} end
81-
assert Enum.zip_reduce_while(left, right, [], reducer) == [4]
82-
end
83-
84-
test "two non lists" do
85-
left = %{a: 1}
86-
right = %{b: 2}
87-
reducer = fn {_, x}, {_, y}, acc -> {:cont, [x + y | acc]} end
88-
assert Enum.zip_reduce_while(left, right, [], reducer) == [3]
89-
end
90-
end
91-
92-
describe "zip_reduce_while/3" do
93-
test "lists" do
94-
enums = [[1, 2], [3, 4]]
95-
reducer = fn values, acc -> {:cont, Enum.sum(values) + acc} end
96-
assert Enum.zip_reduce_while(enums, 0, reducer) == 10
97-
98-
reducer = fn values, acc -> {:cont, [Enum.sum(values) | acc]} end
99-
assert Enum.zip_reduce_while(enums, [], reducer) == [6, 4]
100-
101-
# Suspending the reduction
102-
reducer = fn values, acc -> {:suspend, [Enum.sum(values) | acc]} end
103-
result = Enum.zip_reduce_while(enums, [], reducer)
104-
assert result == [4]
105-
106-
# Halting the reduction
107-
reducer = fn values, acc -> {:halt, [Enum.sum(values) | acc]} end
108-
assert Enum.zip_reduce_while(enums, [], reducer) == [4]
109-
end
110-
111-
test "non lists" do
112-
enums = [%{a: 1, b: 2}, %{c: 3, d: 4}]
113-
114-
reducer = fn values, acc ->
115-
{:cont, Enum.sum(Enum.map(values, &elem(&1, 1))) + acc}
116-
end
117-
118-
assert Enum.zip_reduce_while(enums, 0, reducer) == 10
119-
120-
reducer = fn values, acc ->
121-
{:cont, [Enum.sum(Enum.map(values, &elem(&1, 1))) | acc]}
122-
end
123-
124-
assert Enum.zip_reduce_while(enums, [], reducer) == [6, 4]
125-
126-
# Suspending the reduction
127-
reducer = fn values, acc ->
128-
{:suspend, [Enum.sum(Enum.map(values, &elem(&1, 1))) | acc]}
129-
end
130-
131-
result = Enum.zip_reduce_while(enums, [], reducer)
132-
assert result == [4]
133-
134-
# Halting the reduction
135-
reducer = fn values, acc ->
136-
{:halt, [Enum.sum(Enum.map(values, &elem(&1, 1))) | acc]}
137-
end
138-
139-
assert Enum.zip_reduce_while(enums, [], reducer) == [4]
140-
end
141-
end
142-
14365
test "all?/2" do
14466
assert Enum.all?([2, 4, 6])
14567
refute Enum.all?([2, nil, 4])

0 commit comments

Comments
 (0)