From 7efaf750941f3a1edd5dc03fbe5a290d5ab0236f Mon Sep 17 00:00:00 2001 From: Gert de Pagter Date: Sat, 4 May 2024 08:10:42 +0200 Subject: [PATCH] Add `Vec` versions of the `unique` functions (#472) Vec counterparts for the Dict versions of these functions --- docs/component/vec.md | 3 ++ src/Psl/Internal/Loader.php | 3 ++ src/Psl/Vec/unique.php | 29 +++++++++++++++++++ src/Psl/Vec/unique_by.php | 39 +++++++++++++++++++++++++ src/Psl/Vec/unique_scalar.php | 37 ++++++++++++++++++++++++ tests/unit/Vec/UniqueByTest.php | 37 ++++++++++++++++++++++++ tests/unit/Vec/UniqueScalarTest.php | 44 +++++++++++++++++++++++++++++ tests/unit/Vec/UniqueTest.php | 38 +++++++++++++++++++++++++ 8 files changed, 230 insertions(+) create mode 100644 src/Psl/Vec/unique.php create mode 100644 src/Psl/Vec/unique_by.php create mode 100644 src/Psl/Vec/unique_scalar.php create mode 100644 tests/unit/Vec/UniqueByTest.php create mode 100644 tests/unit/Vec/UniqueScalarTest.php create mode 100644 tests/unit/Vec/UniqueTest.php diff --git a/docs/component/vec.md b/docs/component/vec.md index 90dc80a2..c2074422 100644 --- a/docs/component/vec.md +++ b/docs/component/vec.md @@ -36,6 +36,9 @@ - [sort](./../../src/Psl/Vec/sort.php#L25) - [sort_by](./../../src/Psl/Vec/sort_by.php#L28) - [take](./../../src/Psl/Vec/take.php#L22) +- [unique](./../../src/Psl/Vec/unique.php#L16) +- [unique_by](./../../src/Psl/Vec/unique_by.php#L23) +- [unique_scalar](./../../src/Psl/Vec/unique_scalar.php#L20) - [values](./../../src/Psl/Vec/values.php#L19) - [zip](./../../src/Psl/Vec/zip.php#L37) diff --git a/src/Psl/Internal/Loader.php b/src/Psl/Internal/Loader.php index 4d9ea29e..fed9c596 100644 --- a/src/Psl/Internal/Loader.php +++ b/src/Psl/Internal/Loader.php @@ -155,6 +155,9 @@ final class Loader 'Psl\\Vec\\sort' => 'Psl/Vec/sort.php', 'Psl\\Vec\\sort_by' => 'Psl/Vec/sort_by.php', 'Psl\\Vec\\take' => 'Psl/Vec/take.php', + 'Psl\\Vec\\unique' => 'Psl/Vec/unique.php', + 'Psl\\Vec\\unique_by' => 'Psl/Vec/unique_by.php', + 'Psl\\Vec\\unique_scalar' => 'Psl/Vec/unique_scalar.php', 'Psl\\Vec\\values' => 'Psl/Vec/values.php', 'Psl\\Vec\\zip' => 'Psl/Vec/zip.php', 'Psl\\Math\\abs' => 'Psl/Math/abs.php', diff --git a/src/Psl/Vec/unique.php b/src/Psl/Vec/unique.php new file mode 100644 index 00000000..ae171bc1 --- /dev/null +++ b/src/Psl/Vec/unique.php @@ -0,0 +1,29 @@ + $iterable + * + * @return list + */ +function unique(iterable $iterable): array +{ + return namespace\unique_by( + $iterable, + /** + * @param Tv $v + * + * @return Tv + * + * @pure + */ + static fn($v) => $v, + ); +} diff --git a/src/Psl/Vec/unique_by.php b/src/Psl/Vec/unique_by.php new file mode 100644 index 00000000..01315f3c --- /dev/null +++ b/src/Psl/Vec/unique_by.php @@ -0,0 +1,39 @@ + $iterable + * @param (Closure(Tv): Ts) $scalar_func + * + * @return list + */ +function unique_by(iterable $iterable, Closure $scalar_func): array +{ + /** @var list $unique */ + $unique = []; + /** @var list $original_values */ + $original_values = []; + foreach ($iterable as $v) { + $scalar = $scalar_func($v); + + if (!Iter\contains($unique, $scalar)) { + $unique[] = $scalar; + $original_values[] = $v; + } + } + + return $original_values; +} diff --git a/src/Psl/Vec/unique_scalar.php b/src/Psl/Vec/unique_scalar.php new file mode 100644 index 00000000..81c35f9e --- /dev/null +++ b/src/Psl/Vec/unique_scalar.php @@ -0,0 +1,37 @@ + $iterable + * + * @return list + */ +function unique_scalar(iterable $iterable): array +{ + if (is_array($iterable)) { + return namespace\values(array_unique($iterable)); + } + + return unique_by( + $iterable, + /** + * @param scalar $v + * + * @return scalar + * + * @pure + */ + static fn($v) => $v + ); +} diff --git a/tests/unit/Vec/UniqueByTest.php b/tests/unit/Vec/UniqueByTest.php new file mode 100644 index 00000000..83717734 --- /dev/null +++ b/tests/unit/Vec/UniqueByTest.php @@ -0,0 +1,37 @@ + Str\length($value), + ], + + [ + ['foo', 'bar', '@baz'], + ['foo', '@foo', 'bar', '@bar', '@baz'], + static fn (string $value): string => Str\replace($value, '@', ''), + ], + ]; + } +} diff --git a/tests/unit/Vec/UniqueScalarTest.php b/tests/unit/Vec/UniqueScalarTest.php new file mode 100644 index 00000000..0d5cbce5 --- /dev/null +++ b/tests/unit/Vec/UniqueScalarTest.php @@ -0,0 +1,44 @@ +