Skip to content

Commit aad2d97

Browse files
committed
Implement Enum.equal?
1 parent f1b2980 commit aad2d97

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed

lib/elixir/lib/enum.ex

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,68 @@ defmodule Enum do
328328
end
329329
end
330330

331+
@doc """
332+
Returns true if the first collection is equal to the second, every element in
333+
both collections is iterated through, as soon as an element differs, it
334+
returns false.
335+
336+
## Examples
337+
338+
iex> Enum.equal?([], [])
339+
true
340+
iex> Enum.equal?(1 .. 3, [1, 2, 3])
341+
true
342+
iex> Enum.equal?(1 .. 3, [])
343+
false
344+
345+
"""
346+
@spec equal?(t, t) :: boolean
347+
def equal?(a, b) when is_list(a) and is_list(b) do
348+
a == b
349+
end
350+
351+
def equal?(a, b) when is_list(a) do
352+
equal?(b, a)
353+
end
354+
355+
def equal?(a, b) when is_list(b) do
356+
case I.iterator(a) do
357+
{ _, :stop } ->
358+
b == []
359+
360+
{ iterator, pointer } ->
361+
do_equal?(pointer, iterator, b)
362+
363+
list ->
364+
list == b
365+
end
366+
end
367+
368+
def equal?(a, b) do
369+
case { I.iterator(a), I.iterator(b) } do
370+
{ { _, :stop }, { _, :stop } } ->
371+
true
372+
373+
{ { _, :stop }, { _, _ } } ->
374+
false
375+
376+
{ { _, _ }, { _, :stop } } ->
377+
false
378+
379+
{ { a_iterator, a_pointer }, { b_iterator, b_pointer } } ->
380+
do_equal?(a_pointer, a_iterator, b_pointer, b_iterator)
381+
382+
{ { iterator, pointer }, b } ->
383+
do_equal?(pointer, iterator, b)
384+
385+
{ a, { iterator, pointer } } ->
386+
do_equal?(pointer, iterator, a)
387+
388+
{ a, b } ->
389+
a == b
390+
end
391+
end
392+
331393
@doc """
332394
Filters the collection, i.e. returns only those elements
333395
for which `fun` returns true.
@@ -1120,6 +1182,48 @@ defmodule Enum do
11201182
[]
11211183
end
11221184

1185+
## equal?
1186+
1187+
defp do_equal?({ a, _ }, _, [b | _]) when a != b do
1188+
false
1189+
end
1190+
1191+
defp do_equal?({ _, a_next }, iterator, [_ | b_next]) do
1192+
do_equal?(iterator.(a_next), iterator, b_next)
1193+
end
1194+
1195+
defp do_equal?({ _, _ }, _, []) do
1196+
false
1197+
end
1198+
1199+
defp do_equal?(:stop, _, []) do
1200+
true
1201+
end
1202+
1203+
defp do_equal?(:stop, _, _) do
1204+
false
1205+
end
1206+
1207+
defp do_equal?({ a, _a_next }, _a_iterator, { b, _b_next }, _b_iterator) when a != b do
1208+
false
1209+
end
1210+
1211+
defp do_equal?({ _a, a_next }, a_iterator, { _b, b_next }, b_iterator) do
1212+
do_equal?(a_iterator.(a_next), a_iterator, b_iterator.(b_next), b_iterator)
1213+
end
1214+
1215+
defp do_equal?(:stop, _a_iterator, :stop, _b_iterator) do
1216+
true
1217+
end
1218+
1219+
defp do_equal?(:stop, _a_iterator, _b_pointer, _b_iterator) do
1220+
false
1221+
end
1222+
1223+
defp do_equal?(_a_pointer, _a_iterator, :stop, _b_iterator) do
1224+
false
1225+
end
1226+
11231227
## find
11241228

11251229
defp do_find([h|t], ifnone, fun) do

lib/elixir/test/elixir/enum_test.exs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,16 @@ defmodule EnumTest.List do
8080
refute Enum.empty?([1,2,3])
8181
end
8282

83+
test :equal? do
84+
assert Enum.equal?([], [])
85+
refute Enum.equal?([], [1])
86+
87+
assert Enum.equal?(1 .. 3, [1, 2, 3])
88+
assert Enum.equal?(1 .. 3, 1 .. 3)
89+
refute Enum.equal?(1 .. 3, 1 .. 10)
90+
refute Enum.equal?(1 .. 3, [])
91+
end
92+
8393
test :each do
8494
try do
8595
assert Enum.each([], fn(x) -> x end) == :ok

0 commit comments

Comments
 (0)