From 9755c5e4c892b5ea70df9acb992f4e07a06f364f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Peru?= Date: Thu, 16 Mar 2017 19:26:47 +0100 Subject: [PATCH] Add uniqWith --- README.md | 1 + composer.json | 1 + src/uniq.php | 12 ++++------- src/uniqWith.php | 37 +++++++++++++++++++++++++++++++ tests/uniqWith.php | 54 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 97 insertions(+), 8 deletions(-) create mode 100755 src/uniqWith.php create mode 100755 tests/uniqWith.php diff --git a/README.md b/README.md index 2baa785..b5574f0 100755 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ You can also check code coverage by running ```composer run test:coverage```. - first - last - uniq + - uniqWith - Function composition - flow - compose diff --git a/composer.json b/composer.json index fc022ce..a7c00e3 100755 --- a/composer.json +++ b/composer.json @@ -44,6 +44,7 @@ "src/reverse.php", "src/some.php", "src/uniq.php", + "src/uniqWith.php", "src/zip.php" ] }, diff --git a/src/uniq.php b/src/uniq.php index d2b99c8..4b98427 100755 --- a/src/uniq.php +++ b/src/uniq.php @@ -11,15 +11,11 @@ */ function uniq(...$args) { $uniq = function (array $collection) { - $uniqArray = []; + $isEqual = function ($a, $b) { + return $a == $b; + }; - foreach($collection as $item) { - if (!includes($item, $uniqArray)) { - $uniqArray[] = $item; - } - } - - return $uniqArray; + return uniqWith($isEqual, $collection); }; return curryN($uniq, 1)(...$args); diff --git a/src/uniqWith.php b/src/uniqWith.php new file mode 100755 index 0000000..0fc28b7 --- /dev/null +++ b/src/uniqWith.php @@ -0,0 +1,37 @@ + + */ + $uniqWith = function (Callable $comparator, array $collection) { + $uniqArray = []; + + foreach($collection as $item) { + $isUnique = true; + + for ($i = 0; $i < count($uniqArray); $i++) { + if ($comparator($item, $uniqArray[$i])) { + $isUnique = false; + break; + } + } + + if ($isUnique) { + $uniqArray[] = $item; + } + } + + return $uniqArray; + }; + + return curryN($uniqWith, 2)(...$args); +} diff --git a/tests/uniqWith.php b/tests/uniqWith.php new file mode 100755 index 0000000..c73f120 --- /dev/null +++ b/tests/uniqWith.php @@ -0,0 +1,54 @@ +comparator = function($a, $b) { + return $a === $b; + }; + }); + + it('should return input array without duplicates', function () { + $res = uniqWith($this->comparator, [1, 2, 3, 3 ,4 ,5 , 'orange', 'green', 'orange']); + + expect($res)->toBe([1, 2, 3, 4 ,5 , 'orange', 'green']); + }); + + it('should be curried', function () { + $res = uniqWith($this->comparator); + $res = $res([1, 2, 3, 3 ,4 ,5 , 'orange', 'green', 'orange']); + + expect($res)->toBe([1, 2, 3, 4 ,5 , 'orange', 'green']); + }); + + it('should work with non contiguous arrays', function () { + $res = uniqWith($this->comparator, [0 => 1, 4 => 2, 8 => 2]); + + expect($res)->toBe([1, 2]); + }); + + it('should work for my use case', function () { + $order = [ + 'items' => [ + ['user' => '1444', 'ticket' => '2ae6eeb0-0a75-11e7-93ae-92361f002671'], + ['user' => '1222', 'ticket' => '2ae6eeb0-0a75-11e7-93ae-92361f002671'], + ['user' => '1444', 'ticket' => '2ae6eeb0-0a75-11e7-93ae-92361f002671'] + ] + ]; + + $comparator = function ($a, $b) { + return $a['user'] == $b['user'] && $a['ticket'] == $b['ticket']; + }; + + $expected = [ + ['user' => '1444', 'ticket' => '2ae6eeb0-0a75-11e7-93ae-92361f002671'], + ['user' => '1222', 'ticket' => '2ae6eeb0-0a75-11e7-93ae-92361f002671'] + ]; + + $res = uniqWith($comparator, $order['items']); + + expect($res)->toBe($expected); + }); +});