From 3dabe4d5d9bad39871dbc0c0eec92ecee75f7cc6 Mon Sep 17 00:00:00 2001 From: azjezz Date: Tue, 16 Feb 2021 01:15:37 +0100 Subject: [PATCH] [Arr] deprecate duplicated functions --- src/Psl/Arr/at.php | 3 ++ src/Psl/Arr/contains.php | 6 ++++ src/Psl/Arr/contains_key.php | 6 ++++ src/Psl/Arr/count.php | 2 +- src/Psl/Arr/count_values.php | 29 +++++------------- src/Psl/Arr/fill.php | 6 ++++ src/Psl/Arr/filter_nulls.php | 4 ++- src/Psl/Arr/first.php | 18 ++++++++++-- src/Psl/Arr/first_key.php | 6 ++++ src/Psl/Arr/firstx.php | 13 +++++++-- src/Psl/Arr/flat_map.php | 4 ++- src/Psl/Arr/flatten.php | 2 +- src/Psl/Arr/flip.php | 2 +- src/Psl/Arr/group_by.php | 4 +-- src/Psl/Arr/idx.php | 3 ++ src/Psl/Arr/keys.php | 2 +- src/Psl/Arr/last.php | 14 +++++++-- src/Psl/Arr/last_key.php | 6 ++++ src/Psl/Arr/lastx.php | 13 +++++++-- src/Psl/Arr/random.php | 22 ++++---------- src/Psl/Arr/select_keys.php | 2 +- src/Psl/Collection/Map.php | 17 ++++++----- src/Psl/Collection/MutableMap.php | 17 ++++++----- src/Psl/Collection/MutableVector.php | 20 ++++++------- src/Psl/Collection/Vector.php | 20 ++++++------- src/Psl/DataStructure/PriorityQueue.php | 9 ++---- src/Psl/DataStructure/Queue.php | 5 ++-- src/Psl/DataStructure/Stack.php | 7 ++--- src/Psl/Dict/count_values.php | 39 +++++++++++++++++++++++++ src/Psl/Dict/equal.php | 3 +- src/Psl/Hash/Context.php | 8 +++-- src/Psl/Internal/Loader.php | 2 ++ src/Psl/Iter/Iterator.php | 9 +++--- src/Psl/Iter/enumerate.php | 5 ++++ src/Psl/Iter/product.php | 5 ++-- src/Psl/Iter/random.php | 18 ++++++++---- src/Psl/Password/hash.php | 8 +++-- src/Psl/Type/Internal/ShapeType.php | 6 ++-- src/Psl/Vec/enumerate.php | 25 ++++++++++++++++ tests/Psl/Arr/RandomTest.php | 2 +- tests/Psl/Dict/MapTest.php | 2 +- tests/Psl/Vec/EnumerateTest.php | 31 ++++++++++++++++++++ 42 files changed, 288 insertions(+), 137 deletions(-) create mode 100644 src/Psl/Dict/count_values.php create mode 100644 src/Psl/Vec/enumerate.php create mode 100644 tests/Psl/Vec/EnumerateTest.php diff --git a/src/Psl/Arr/at.php b/src/Psl/Arr/at.php index ffb40fbd..42a20082 100644 --- a/src/Psl/Arr/at.php +++ b/src/Psl/Arr/at.php @@ -21,9 +21,12 @@ * @psalm-pure * * @throws Psl\Exception\InvariantViolationException If $key is out-of-bounds. + * + * @deprecated use `$array[$key]` instead. */ function at(array $array, $key) { + /** @psalm-suppress DeprecatedFunction */ Psl\invariant(contains_key($array, $key), 'Key (%s) is out-of-bounds.', $key); /** @psalm-var Tv */ diff --git a/src/Psl/Arr/contains.php b/src/Psl/Arr/contains.php index f34ddc78..87018042 100644 --- a/src/Psl/Arr/contains.php +++ b/src/Psl/Arr/contains.php @@ -4,6 +4,8 @@ namespace Psl\Arr; +use Psl\Iter; + /** * Returns true if the given array contains the value. Strict equality is * used. @@ -15,6 +17,10 @@ * @psalm-param Tv $value * * @psalm-pure + * + * @deprecated use `Iter\contains` instead. + * + * @see Iter\contains() */ function contains(array $array, $value): bool { diff --git a/src/Psl/Arr/contains_key.php b/src/Psl/Arr/contains_key.php index 66399ef0..cf36cc60 100644 --- a/src/Psl/Arr/contains_key.php +++ b/src/Psl/Arr/contains_key.php @@ -4,6 +4,8 @@ namespace Psl\Arr; +use Psl\Iter; + use function array_key_exists; /** @@ -16,6 +18,10 @@ * @psalm-param Tk $key * * @psalm-pure + * + * @deprecated use `Iter\contains_key()` instead. + * + * @see Iter\contains_key() */ function contains_key(array $array, $key): bool { diff --git a/src/Psl/Arr/count.php b/src/Psl/Arr/count.php index ed94e5ec..ac79b77a 100644 --- a/src/Psl/Arr/count.php +++ b/src/Psl/Arr/count.php @@ -30,7 +30,7 @@ * * @psalm-pure * - * @deprecated since 1.2, use Iter\count instead. + * @deprecated use Iter\count instead. * * @see Iter\count() */ diff --git a/src/Psl/Arr/count_values.php b/src/Psl/Arr/count_values.php index 278a1566..9f6ae2bc 100644 --- a/src/Psl/Arr/count_values.php +++ b/src/Psl/Arr/count_values.php @@ -4,8 +4,7 @@ namespace Psl\Arr; -use Psl; -use Psl\Type; +use Psl\Dict; /** * Returns a new array mapping each value to the number of times it appears @@ -13,29 +12,15 @@ * * @psalm-template T of array-key * - * @psalm-param list $values + * @psalm-param iterable $values * * @psalm-return array * - * @psalm-pure + * @deprecated use `Dict\count_values` instead. + * + * @see Dict\count_values() */ -function count_values(array $values): array +function count_values(iterable $values): array { - /** @psalm-var array $result */ - $result = []; - - foreach ($values as $value) { - Psl\invariant( - Type\is_arraykey($value), - 'Expected all values to be of type array-key, value of type (%s) provided.', - gettype($value) - ); - - /** @psalm-var int $count */ - $count = idx($result, $value, 0); - /** @psalm-var T $value */ - $result[$value] = $count + 1; - } - - return $result; + return Dict\count_values($values); } diff --git a/src/Psl/Arr/fill.php b/src/Psl/Arr/fill.php index ef2b9ec5..46cf5202 100644 --- a/src/Psl/Arr/fill.php +++ b/src/Psl/Arr/fill.php @@ -4,6 +4,8 @@ namespace Psl\Arr; +use Psl\Vec; + use function array_fill; /** @@ -16,6 +18,10 @@ * @psalm-return array * * @psalm-pure + * + * @deprecated use `Vec\fill` instead. + * + * @see Vec\fill() */ function fill($value, int $start_index, int $num): array { diff --git a/src/Psl/Arr/filter_nulls.php b/src/Psl/Arr/filter_nulls.php index 54c217b7..7465eb8b 100644 --- a/src/Psl/Arr/filter_nulls.php +++ b/src/Psl/Arr/filter_nulls.php @@ -19,7 +19,9 @@ * * @psalm-return list * - * @deprecated since 1.2, use Vec\filter_nulls instead. + * @deprecated use `Vec\filter_nulls` instead. + * + * @see Vec\filter_nulls() */ function filter_nulls(iterable $iterable): array { diff --git a/src/Psl/Arr/first.php b/src/Psl/Arr/first.php index 29e429f1..1681d03b 100644 --- a/src/Psl/Arr/first.php +++ b/src/Psl/Arr/first.php @@ -4,6 +4,8 @@ namespace Psl\Arr; +use Psl\Iter; + /** * Get the first value of an array, If the array is empty, null will be returned. * @@ -15,12 +17,22 @@ * @psalm-return Tv|null * * @psalm-pure + * + * @deprecated use `Iter\first()` instead. + * + * @see Iter\first() */ function first(array $array) { - /** @psalm-var Tk|null $first */ + /** + * @psalm-var Tk|null $first + * @psalm-suppress DeprecatedFunction + */ $first = first_key($array); - /** @psalm-var Tv|null */ - return null !== $first ? at($array, $first) : null; + if (null === $first) { + return null; + } + + return $array[$first]; } diff --git a/src/Psl/Arr/first_key.php b/src/Psl/Arr/first_key.php index 3991c17b..1b12bc72 100644 --- a/src/Psl/Arr/first_key.php +++ b/src/Psl/Arr/first_key.php @@ -4,6 +4,8 @@ namespace Psl\Arr; +use Psl\Iter; + use function array_key_first; /** @@ -16,6 +18,10 @@ * @psalm-return Tk|null * * @psalm-pure + * + * @deprecated use `Iter\first_key` instead. + * + * @see Iter\first_key() */ function first_key(array $array) { diff --git a/src/Psl/Arr/firstx.php b/src/Psl/Arr/firstx.php index 33a4cf40..ac83d421 100644 --- a/src/Psl/Arr/firstx.php +++ b/src/Psl/Arr/firstx.php @@ -5,6 +5,7 @@ namespace Psl\Arr; use Psl; +use Psl\Iter; /** * Get the first value of an array, If the array is empty, an InvariantViolationException @@ -20,13 +21,19 @@ * @psalm-pure * * @throws Psl\Exception\InvariantViolationException If $array is empty. + * + * @deprecated use `Iter\first` instead. + * + * @see Iter\first() */ function firstx(array $array) { - /** @psalm-var Tk|null $first */ + /** + * @psalm-var Tk|null $first + * @psalm-suppress DeprecatedFunction + */ $first = first_key($array); Psl\invariant(null !== $first, 'Expected a non-empty array.'); - /** @psalm-var Tv */ - return at($array, $first); + return $array[$first]; } diff --git a/src/Psl/Arr/flat_map.php b/src/Psl/Arr/flat_map.php index e5fce7c3..6e6dfddc 100644 --- a/src/Psl/Arr/flat_map.php +++ b/src/Psl/Arr/flat_map.php @@ -16,7 +16,9 @@ * * @psalm-return list * - * @deprecated since 1.2, use Vec\flat_map instead. + * @deprecated use `Vec\flat_map` instead. + * + * @see Vec\flat_map() */ function flat_map(iterable $iterable, callable $mapper): array { diff --git a/src/Psl/Arr/flatten.php b/src/Psl/Arr/flatten.php index f67a38ba..55f18a5c 100644 --- a/src/Psl/Arr/flatten.php +++ b/src/Psl/Arr/flatten.php @@ -29,7 +29,7 @@ * * @deprecated use `Dict\flatten` instead. * - * @see Dict\flatten + * @see Dict\flatten() */ function flatten(iterable $iterables): array { diff --git a/src/Psl/Arr/flip.php b/src/Psl/Arr/flip.php index 0cb4a08a..f3b88f05 100644 --- a/src/Psl/Arr/flip.php +++ b/src/Psl/Arr/flip.php @@ -24,7 +24,7 @@ * * @deprecated use `Dict\flip` instead. * - * @see Dict\flip + * @see Dict\flip() */ function flip(array $array): array { diff --git a/src/Psl/Arr/group_by.php b/src/Psl/Arr/group_by.php index 0d5f2b01..0bc45c4d 100644 --- a/src/Psl/Arr/group_by.php +++ b/src/Psl/Arr/group_by.php @@ -37,9 +37,9 @@ * * @psalm-return array> * - * @deprecated use Dict\group_by + * @deprecated use `Dict\group_by` instead. * - * @see Dict\group_by + * @see Dict\group_by() */ function group_by(iterable $values, callable $key_func): array { diff --git a/src/Psl/Arr/idx.php b/src/Psl/Arr/idx.php index e2081be5..d240f094 100644 --- a/src/Psl/Arr/idx.php +++ b/src/Psl/Arr/idx.php @@ -29,9 +29,12 @@ * @psalm-return Tv * * @psalm-pure + * + * @deprecated use `$array[$index] ?? $default` instead. */ function idx(array $array, $index, $default = null) { + /** @psalm-suppress DeprecatedFunction */ if (contains_key($array, $index)) { return $array[$index]; } diff --git a/src/Psl/Arr/keys.php b/src/Psl/Arr/keys.php index 06a7c625..afff41c7 100644 --- a/src/Psl/Arr/keys.php +++ b/src/Psl/Arr/keys.php @@ -16,7 +16,7 @@ * * @psalm-return list * - * @deprecated since 1.2, use Vec\keys instead. + * @deprecated use `Vec\keys` instead. * * @see Vec\keys() */ diff --git a/src/Psl/Arr/last.php b/src/Psl/Arr/last.php index 037e054f..235f421c 100644 --- a/src/Psl/Arr/last.php +++ b/src/Psl/Arr/last.php @@ -4,6 +4,8 @@ namespace Psl\Arr; +use Psl\Iter; + /** * Get the last value of an array, if the array is empty, returns null. * @@ -15,15 +17,21 @@ * @psalm-return Tv|null * * @psalm-pure + * + * @deprecated use `Iter\last` instead. + * + * @see Iter\last() */ function last(array $array) { - /** @psalm-var Tk|null $last */ + /** + * @psalm-var Tk|null $last + * @psalm-suppress DeprecatedFunction + */ $last = last_key($array); if (null === $last) { return null; } - /** @psalm-suppress MissingThrowsDocblock - we are sure that $last is within-bounds. */ - return at($array, $last); + return $array[$last]; } diff --git a/src/Psl/Arr/last_key.php b/src/Psl/Arr/last_key.php index 28e83ca5..74f08021 100644 --- a/src/Psl/Arr/last_key.php +++ b/src/Psl/Arr/last_key.php @@ -4,6 +4,8 @@ namespace Psl\Arr; +use Psl\Iter; + use function array_key_last; /** @@ -17,6 +19,10 @@ * @psalm-return Tk|null * * @psalm-pure + * + * @deprecated use `Iter\last_key` instead. + * + * @see Iter\last_key() */ function last_key(array $array) { diff --git a/src/Psl/Arr/lastx.php b/src/Psl/Arr/lastx.php index 4e7ee2c0..175a1fc3 100644 --- a/src/Psl/Arr/lastx.php +++ b/src/Psl/Arr/lastx.php @@ -5,6 +5,7 @@ namespace Psl\Arr; use Psl; +use Psl\Iter; /** * Get the last value of an array, If the array is empty, an InvariantViolationException @@ -20,13 +21,19 @@ * @psalm-pure * * @throws Psl\Exception\InvariantViolationException If $array is empty. + * + * @deprecated use `Iter\last` instead. + * + * @see Iter\last() */ function lastx(array $array) { - /** @psalm-var Tk|null $last */ + /** + * @psalm-var Tk|null $last + * @psalm-suppress DeprecatedFunction + */ $last = last_key($array); Psl\invariant(null !== $last, 'Expected a non-empty array.'); - /** @psalm-var Tv */ - return at($array, $last); + return $array[$last]; } diff --git a/src/Psl/Arr/random.php b/src/Psl/Arr/random.php index 5e7e634e..a180a573 100644 --- a/src/Psl/Arr/random.php +++ b/src/Psl/Arr/random.php @@ -6,8 +6,6 @@ use Psl; use Psl\Iter; -use Psl\PseudoRandom; -use Psl\Vec; /** * Retrieve a random value from a non-empty array. @@ -20,22 +18,12 @@ * @psalm-return Tv * * @throws Psl\Exception\InvariantViolationException If $values is empty. + * + * @deprecated use `Iter\random` instead. + * + * @see Iter\random() */ function random(array $values) { - $size = Iter\count($values); - - Psl\invariant(0 !== $size, 'Expected a non-empty-array.'); - - /** @psalm-var list $shuffled */ - $shuffled = Vec\shuffle($values); - - - if (1 === $size) { - /** @psalm-var Tv */ - return $shuffled[0]; - } - - /** @psalm-suppress MissingThrowsDocblock */ - return at($shuffled, PseudoRandom\int(0, $size - 1)); + return Iter\random($values); } diff --git a/src/Psl/Arr/select_keys.php b/src/Psl/Arr/select_keys.php index 8d5cdd69..cb162ee3 100644 --- a/src/Psl/Arr/select_keys.php +++ b/src/Psl/Arr/select_keys.php @@ -21,7 +21,7 @@ * * @deprecated use `Dict\select_keys` instead. * - * @see Dict\select_keys + * @see Dict\select_keys() */ function select_keys(array $array, array $keys): array { diff --git a/src/Psl/Collection/Map.php b/src/Psl/Collection/Map.php index 8f51a55d..d3fd4fa9 100644 --- a/src/Psl/Collection/Map.php +++ b/src/Psl/Collection/Map.php @@ -5,7 +5,6 @@ namespace Psl\Collection; use Psl; -use Psl\Arr; use Psl\Dict; use Psl\Iter; use Psl\Vec; @@ -43,7 +42,7 @@ public function __construct(iterable $elements) */ public function first() { - return Arr\first($this->elements); + return Iter\first($this->elements); } /** @@ -54,7 +53,7 @@ public function first() */ public function firstKey() { - return Arr\first_key($this->elements); + return Iter\first_key($this->elements); } /** @@ -65,7 +64,7 @@ public function firstKey() */ public function last() { - return Arr\last($this->elements); + return Iter\last($this->elements); } /** @@ -76,7 +75,7 @@ public function last() */ public function lastKey() { - return Arr\last_key($this->elements); + return Iter\last_key($this->elements); } /** @@ -157,7 +156,9 @@ public function jsonSerialize(): array */ public function at($k) { - return Arr\at($this->elements, $k); + Psl\invariant($this->contains($k), 'Key (%s) is out-of-bounds.', $k); + + return $this->elements[$k]; } /** @@ -167,7 +168,7 @@ public function at($k) */ public function contains($k): bool { - return Arr\contains_key($this->elements, $k); + return Iter\contains_key($this->elements, $k); } /** @@ -179,7 +180,7 @@ public function contains($k): bool */ public function get($k) { - return Arr\idx($this->elements, $k); + return $this->elements[$k] ?? null; } diff --git a/src/Psl/Collection/MutableMap.php b/src/Psl/Collection/MutableMap.php index c34a00cd..81d51ce0 100644 --- a/src/Psl/Collection/MutableMap.php +++ b/src/Psl/Collection/MutableMap.php @@ -5,7 +5,6 @@ namespace Psl\Collection; use Psl; -use Psl\Arr; use Psl\Dict; use Psl\Iter; use Psl\Vec; @@ -41,7 +40,7 @@ public function __construct(iterable $elements) */ public function first() { - return Arr\first($this->elements); + return Iter\first($this->elements); } /** @@ -52,7 +51,7 @@ public function first() */ public function firstKey() { - return Arr\first_key($this->elements); + return Iter\first_key($this->elements); } /** @@ -63,7 +62,7 @@ public function firstKey() */ public function last() { - return Arr\last($this->elements); + return Iter\last($this->elements); } /** @@ -74,7 +73,7 @@ public function last() */ public function lastKey() { - return Arr\last_key($this->elements); + return Iter\last_key($this->elements); } /** @@ -155,7 +154,9 @@ public function jsonSerialize(): array */ public function at($k) { - return Arr\at($this->elements, $k); + Psl\invariant($this->contains($k), 'Key (%s) is out-of-bounds.', $k); + + return $this->elements[$k]; } /** @@ -165,7 +166,7 @@ public function at($k) */ public function contains($k): bool { - return Arr\contains_key($this->elements, $k); + return Iter\contains_key($this->elements, $k); } /** @@ -177,7 +178,7 @@ public function contains($k): bool */ public function get($k) { - return Arr\idx($this->elements, $k); + return $this->elements[$k] ?? null; } /** diff --git a/src/Psl/Collection/MutableVector.php b/src/Psl/Collection/MutableVector.php index aaf17d7a..9c60fa6a 100644 --- a/src/Psl/Collection/MutableVector.php +++ b/src/Psl/Collection/MutableVector.php @@ -5,7 +5,6 @@ namespace Psl\Collection; use Psl; -use Psl\Arr; use Psl\Dict; use Psl\Iter; use Psl\Vec; @@ -42,7 +41,7 @@ public function __construct(iterable $elements) */ public function first() { - return Arr\first($this->elements); + return Iter\first($this->elements); } /** @@ -53,7 +52,7 @@ public function first() */ public function last() { - return Arr\last($this->elements); + return Iter\last($this->elements); } /** @@ -113,7 +112,9 @@ public function jsonSerialize(): array */ public function at($k) { - return Arr\at($this->elements, $k); + Psl\invariant($this->contains($k), 'Key (%s) is out-of-bounds.', $k); + + return $this->elements[$k]; } /** @@ -123,7 +124,7 @@ public function at($k) */ public function contains($k): bool { - return Arr\contains_key($this->elements, $k); + return Iter\contains_key($this->elements, $k); } /** @@ -135,7 +136,7 @@ public function contains($k): bool */ public function get($k) { - return Arr\idx($this->elements, $k); + return $this->elements[$k] ?? null; } /** @@ -146,10 +147,7 @@ public function get($k) */ public function firstKey(): ?int { - /** @var int|null $key */ - $key = Arr\first_key($this->elements); - - return $key; + return Iter\first_key($this->elements); } /** @@ -160,7 +158,7 @@ public function firstKey(): ?int */ public function lastKey(): ?int { - return Arr\last_key($this->elements); + return Iter\last_key($this->elements); } /** diff --git a/src/Psl/Collection/Vector.php b/src/Psl/Collection/Vector.php index f2010d0b..519345eb 100644 --- a/src/Psl/Collection/Vector.php +++ b/src/Psl/Collection/Vector.php @@ -5,7 +5,6 @@ namespace Psl\Collection; use Psl; -use Psl\Arr; use Psl\Dict; use Psl\Iter; use Psl\Vec; @@ -44,7 +43,7 @@ public function __construct(iterable $elements) */ public function first() { - return Arr\first($this->elements); + return Iter\first($this->elements); } /** @@ -55,7 +54,7 @@ public function first() */ public function last() { - return Arr\last($this->elements); + return Iter\last($this->elements); } /** @@ -116,7 +115,9 @@ public function jsonSerialize(): array */ public function at($k) { - return Arr\at($this->elements, $k); + Psl\invariant($this->contains($k), 'Key (%s) is out-of-bounds.', $k); + + return $this->elements[$k]; } /** @@ -126,7 +127,7 @@ public function at($k) */ public function contains($k): bool { - return Arr\contains_key($this->elements, $k); + return Iter\contains_key($this->elements, $k); } /** @@ -138,7 +139,7 @@ public function contains($k): bool */ public function get($k) { - return Arr\idx($this->elements, $k); + return $this->elements[$k] ?? null; } /** @@ -149,10 +150,7 @@ public function get($k) */ public function firstKey(): ?int { - /** @var int|null $key */ - $key = Arr\first_key($this->elements); - - return $key; + return Iter\first_key($this->elements); } /** @@ -163,7 +161,7 @@ public function firstKey(): ?int */ public function lastKey(): ?int { - return Arr\last_key($this->elements); + return Iter\last_key($this->elements); } /** diff --git a/src/Psl/DataStructure/PriorityQueue.php b/src/Psl/DataStructure/PriorityQueue.php index 6ef88748..c1e40ff1 100644 --- a/src/Psl/DataStructure/PriorityQueue.php +++ b/src/Psl/DataStructure/PriorityQueue.php @@ -5,7 +5,6 @@ namespace Psl\DataStructure; use Psl; -use Psl\Arr; use Psl\Dict; use Psl\Iter; use Psl\Math; @@ -55,10 +54,10 @@ public function peek() $priority = Math\max($keys) ?? 0; // Retrieve the list of nodes with the priority `$priority`. - $nodes = Arr\idx($this->queue, $priority, []); + $nodes = $this->queue[$priority] ?? []; // Retrieve the first node of the list. - return Arr\first($nodes); + return Iter\first($nodes); } /** @@ -111,10 +110,8 @@ private function drop(): void /** * Retrieve the list of nodes with the priority `$priority`. - * - * @psalm-suppress MissingThrowsDocblock */ - $nodes = Arr\at($this->queue, $priority); + $nodes = $this->queue[$priority]; // If the list contained only this node, // remove the list of nodes with priority `$priority`. diff --git a/src/Psl/DataStructure/Queue.php b/src/Psl/DataStructure/Queue.php index 689aa16f..0e19b538 100644 --- a/src/Psl/DataStructure/Queue.php +++ b/src/Psl/DataStructure/Queue.php @@ -5,7 +5,6 @@ namespace Psl\DataStructure; use Psl; -use Psl\Arr; use Psl\Dict; use Psl\Iter; use Psl\Vec; @@ -42,7 +41,7 @@ public function enqueue($node): void */ public function peek() { - return Arr\first($this->queue); + return Iter\first($this->queue); } /** @@ -72,7 +71,7 @@ public function dequeue() { Psl\invariant(0 !== $this->count(), 'Cannot dequeue a node from an empty Queue.'); - $node = Arr\firstx($this->queue); + $node = $this->queue[0]; $this->queue = Vec\values(Dict\drop($this->queue, 1)); return $node; diff --git a/src/Psl/DataStructure/Stack.php b/src/Psl/DataStructure/Stack.php index a1aaccbc..5cee4d13 100644 --- a/src/Psl/DataStructure/Stack.php +++ b/src/Psl/DataStructure/Stack.php @@ -5,7 +5,6 @@ namespace Psl\DataStructure; use Psl; -use Psl\Arr; use Psl\Dict; use Psl\Iter; use Psl\Vec; @@ -42,7 +41,7 @@ public function push($item): void */ public function peek() { - return Arr\last($this->items); + return Iter\last($this->items); } /** @@ -70,9 +69,9 @@ public function pull() */ public function pop() { - Psl\invariant(0 !== $this->count(), 'Cannot pop an item from an empty Stack.'); + Psl\invariant(0 !== ($i = $this->count()), 'Cannot pop an item from an empty Stack.'); - $tail = Arr\lastx($this->items); + $tail = $this->items[$i - 1]; $this->items = Vec\values(Dict\take($this->items, $this->count() - 1)); return $tail; diff --git a/src/Psl/Dict/count_values.php b/src/Psl/Dict/count_values.php new file mode 100644 index 00000000..bacaa231 --- /dev/null +++ b/src/Psl/Dict/count_values.php @@ -0,0 +1,39 @@ + $values + * + * @psalm-return array + */ +function count_values(iterable $values): array +{ + /** @psalm-var array $result */ + $result = []; + + foreach ($values as $value) { + Psl\invariant( + Type\is_arraykey($value), + 'Expected all values to be of type array-key, value of type (%s) provided.', + gettype($value) + ); + + /** @psalm-var int $count */ + $count = $result[$value] ?? 0; + /** @psalm-var T $value */ + $result[$value] = $count + 1; + } + + return $result; +} diff --git a/src/Psl/Dict/equal.php b/src/Psl/Dict/equal.php index de90d7f5..4cfbb5f5 100644 --- a/src/Psl/Dict/equal.php +++ b/src/Psl/Dict/equal.php @@ -4,7 +4,6 @@ namespace Psl\Dict; -use Psl\Arr; use Psl\Iter; /** @@ -28,7 +27,7 @@ function equal(array $first, array $second): bool } foreach ($first as $k => $v) { - if (!Arr\contains_key($second, $k) || $second[$k] !== $v) { + if (!Iter\contains_key($second, $k) || $second[$k] !== $v) { return false; } } diff --git a/src/Psl/Hash/Context.php b/src/Psl/Hash/Context.php index 4cc273dc..aec52bd8 100644 --- a/src/Psl/Hash/Context.php +++ b/src/Psl/Hash/Context.php @@ -6,7 +6,7 @@ use HashContext; use Psl; -use Psl\Arr; +use Psl\Iter; use Psl\Str; use function hash_final; @@ -46,8 +46,9 @@ private function __construct(HashContext $internal_context) */ public static function forAlgorithm(string $algorithm): Context { + /** @psalm-suppress ImpureFunctionCall */ Psl\invariant( - Arr\contains(algorithms(), $algorithm), + Iter\contains(algorithms(), $algorithm), 'Expected a valid hashing algorithm, "%s" given.', $algorithm, ); @@ -65,8 +66,9 @@ public static function forAlgorithm(string $algorithm): Context */ public static function hmac(string $algorithm, string $key): Context { + /** @psalm-suppress ImpureFunctionCall */ Psl\invariant( - Arr\contains(Hmac\algorithms(), $algorithm), + Iter\contains(Hmac\algorithms(), $algorithm), 'Expected a hashing algorithms suitable for HMAC, "%s" given.', $algorithm ); diff --git a/src/Psl/Internal/Loader.php b/src/Psl/Internal/Loader.php index ebdf7758..93051170 100644 --- a/src/Psl/Internal/Loader.php +++ b/src/Psl/Internal/Loader.php @@ -97,6 +97,7 @@ final class Loader 'Psl\Arr\map_keys', 'Psl\Arr\map_with_key', 'Psl\Dict\associate', + 'Psl\Dict\count_values', 'Psl\Dict\drop', 'Psl\Dict\drop_while', 'Psl\Dict\equal', @@ -196,6 +197,7 @@ final class Loader 'Psl\Vec\chunk', 'Psl\Vec\chunk_with_keys', 'Psl\Vec\concat', + 'Psl\Vec\enumerate', 'Psl\Vec\fill', 'Psl\Vec\filter_nulls', 'Psl\Vec\flat_map', diff --git a/src/Psl/Iter/Iterator.php b/src/Psl/Iter/Iterator.php index e8b349bd..beeae723 100644 --- a/src/Psl/Iter/Iterator.php +++ b/src/Psl/Iter/Iterator.php @@ -7,7 +7,6 @@ use Countable; use Generator; use Psl; -use Psl\Arr; use SeekableIterator; /** @@ -91,7 +90,7 @@ public static function create(iterable $iterable): Iterator public function current() { Psl\invariant($this->valid(), 'The Iterator is invalid.'); - if (!Arr\contains_key($this->entries, $this->position)) { + if (!contains_key($this->entries, $this->position)) { $this->progress(); } @@ -108,7 +107,7 @@ public function next(): void return; } - if (Arr\contains_key($this->entries, $this->position + 1)) { + if (contains_key($this->entries, $this->position + 1)) { return; } @@ -131,7 +130,7 @@ public function next(): void public function key() { Psl\invariant($this->valid(), 'The Iterator is invalid.'); - if (!Arr\contains_key($this->entries, $this->position)) { + if (!contains_key($this->entries, $this->position)) { $this->progress(); } @@ -143,7 +142,7 @@ public function key() */ public function valid(): bool { - if (Arr\contains_key($this->entries, $this->position)) { + if (contains_key($this->entries, $this->position)) { return true; } diff --git a/src/Psl/Iter/enumerate.php b/src/Psl/Iter/enumerate.php index 50aa989c..52483f64 100644 --- a/src/Psl/Iter/enumerate.php +++ b/src/Psl/Iter/enumerate.php @@ -5,6 +5,7 @@ namespace Psl\Iter; use Generator; +use Psl\Vec; /** * Converts an iterable of key and value pairs, into a generator of entries. @@ -15,6 +16,10 @@ * @psalm-param iterable $iterable * * @psalm-return Iterator + * + * @deprecated use `Vec\enumerate` instead. + * + * @see Vec\enumerate() */ function enumerate(iterable $iterable): Iterator { diff --git a/src/Psl/Iter/product.php b/src/Psl/Iter/product.php index 217f8b40..0dec7d5c 100644 --- a/src/Psl/Iter/product.php +++ b/src/Psl/Iter/product.php @@ -5,7 +5,6 @@ namespace Psl\Iter; use Generator; -use Psl\Arr; use Psl\Dict; use Psl\Vec; @@ -51,8 +50,8 @@ function product(iterable ...$iterables): Iterator /** @psalm-var list $keyTuple */ /** @psalm-var list $valueTuple */ - $keyTuple = Arr\fill(null, 0, $numIterators); - $valueTuple = Arr\fill(null, 0, $numIterators); + $keyTuple = Vec\fill($numIterators, null); + $valueTuple = Vec\fill($numIterators, null); $i = -1; while (true) { while (++$i < $numIterators - 1) { diff --git a/src/Psl/Iter/random.php b/src/Psl/Iter/random.php index 86d0dfe2..d8a7f822 100644 --- a/src/Psl/Iter/random.php +++ b/src/Psl/Iter/random.php @@ -5,7 +5,7 @@ namespace Psl\Iter; use Psl; -use Psl\Arr; +use Psl\PseudoRandom; use Psl\Vec; /** @@ -26,10 +26,18 @@ function random(iterable $iterable) // this helps us avoids an issue when the iterable is a generator where // would exhaust it when calling `is_empty`, which results in an // exception at the `to_array` call. - $array = Vec\values($iterable); + $values = Vec\values($iterable); + $size = count($values); - Psl\invariant(!is_empty($array), 'Expected a non-empty iterable.'); + Psl\invariant(0 !== $size, 'Expected a non-empty iterable.'); - /** @psalm-var Tv */ - return Arr\random($array); + /** @psalm-var list $shuffled */ + $shuffled = Vec\shuffle($values); + + if (1 === $size) { + /** @psalm-var Tv */ + return $shuffled[0]; + } + + return $shuffled[PseudoRandom\int(0, $size - 1)]; } diff --git a/src/Psl/Password/hash.php b/src/Psl/Password/hash.php index d4d63cb0..1e67332f 100644 --- a/src/Psl/Password/hash.php +++ b/src/Psl/Password/hash.php @@ -5,7 +5,7 @@ namespace Psl\Password; use Psl; -use Psl\Arr; +use Psl\Iter; use function password_hash; @@ -31,10 +31,12 @@ */ function hash(string $password, string $algorithm = DEFAULT_ALGORITHM, array $options = []): string { - Psl\invariant(Arr\contains(algorithms(), $algorithm), 'Unsupported algorithm "%s".', $algorithm); + /** @psalm-suppress ImpureFunctionCall */ + Psl\invariant(Iter\contains(algorithms(), $algorithm), 'Unsupported algorithm "%s".', $algorithm); if (DEFAULT_ALGORITHM === $algorithm) { $algorithm = PASSWORD_BCRYPT; - Psl\invariant(!Arr\contains_key($options, 'salt'), 'The "salt" option is not supported.'); + /** @psalm-suppress ImpureFunctionCall */ + Psl\invariant(!Iter\contains_key($options, 'salt'), 'The "salt" option is not supported.'); } /** @var false|string $hash */ diff --git a/src/Psl/Type/Internal/ShapeType.php b/src/Psl/Type/Internal/ShapeType.php index 94953143..52fed60e 100644 --- a/src/Psl/Type/Internal/ShapeType.php +++ b/src/Psl/Type/Internal/ShapeType.php @@ -4,7 +4,7 @@ namespace Psl\Type\Internal; -use Psl\Arr; +use Psl\Iter; use Psl\Str; use Psl\Type; use Psl\Type\Exception\AssertException; @@ -59,7 +59,7 @@ public function coerce($value): array $trace = $this->getTrace()->withFrame('array{' . $element_name . ': _}'); /** @var Type\Type $type */ $type = $type->withTrace($trace); - if (Arr\contains_key($array, $element)) { + if (Iter\contains_key($array, $element)) { $result[$element] = $type->coerce($array[$element]); continue; @@ -100,7 +100,7 @@ public function assert($value): array $trace = $this->getTrace()->withFrame('array{' . $element_name . ': _}'); /** @var Type\Type $type */ $type = $type->withTrace($trace); - if (Arr\contains_key($value, $element)) { + if (Iter\contains_key($value, $element)) { $result[$element] = $type->assert($value[$element]); continue; diff --git a/src/Psl/Vec/enumerate.php b/src/Psl/Vec/enumerate.php new file mode 100644 index 00000000..a028d2a0 --- /dev/null +++ b/src/Psl/Vec/enumerate.php @@ -0,0 +1,25 @@ + $iterable + * + * @return list + */ +function enumerate(iterable $iterable): array +{ + $result = []; + foreach ($iterable as $k => $v) { + $result[] = [$k, $v]; + } + + return $result; +} diff --git a/tests/Psl/Arr/RandomTest.php b/tests/Psl/Arr/RandomTest.php index 94961fb5..be538ff0 100644 --- a/tests/Psl/Arr/RandomTest.php +++ b/tests/Psl/Arr/RandomTest.php @@ -30,7 +30,7 @@ public function testRandomWithOneItem(): void public function testRandomThrowsWhenTheGivenArrayIsEmpty(): void { $this->expectException(Exception\InvariantViolationException::class); - $this->expectExceptionMessage('Expected a non-empty-array.'); + $this->expectExceptionMessage('Expected a non-empty iterable.'); Arr\random([]); } diff --git a/tests/Psl/Dict/MapTest.php b/tests/Psl/Dict/MapTest.php index 27e375f6..4166b9f7 100644 --- a/tests/Psl/Dict/MapTest.php +++ b/tests/Psl/Dict/MapTest.php @@ -24,6 +24,6 @@ public function provideData(): iterable yield [[1, 2, 3], [1, 2, 3], static fn (int $v): int => $v]; yield [[2, 4, 6], [1, 2, 3], static fn (int $v): int => $v * 2]; yield [['1', '2', '3'], [1, 2, 3], static fn (int $v): string => (string)$v]; - yield [[], [], static fn (int $k): string => (string)$v]; + yield [[], [], static fn (int $v): string => (string)$v]; } } diff --git a/tests/Psl/Vec/EnumerateTest.php b/tests/Psl/Vec/EnumerateTest.php new file mode 100644 index 00000000..b2031832 --- /dev/null +++ b/tests/Psl/Vec/EnumerateTest.php @@ -0,0 +1,31 @@ + 'b', 'c' => 'd']]; + yield [[['a', 'b'], ['a', 'b'], ['a', 'b']], (static function () { + yield 'a' => 'b'; + yield 'a' => 'b'; + yield 'a' => 'b'; + })()]; + yield [[['a', null], ['b', 0]], ['a' => null, 'b' => 0]]; + } +}