diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index f3ac2ad03..dc23072e5 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -22,4 +22,4 @@ jobs: run: "composer update --no-interaction --no-progress" - name: "running static analysis ( psalm )" - run: "vendor/bin/psalm --output-format=github --shepherd --stats" + run: "vendor/bin/psalm --shepherd --stats" diff --git a/src/Psl/Arr/drop.php b/src/Psl/Arr/drop.php index cd6992b85..fd8d6fc23 100644 --- a/src/Psl/Arr/drop.php +++ b/src/Psl/Arr/drop.php @@ -5,6 +5,7 @@ namespace Psl\Arr; use Psl; +use Psl\Dict; /** * Drops the first n items from an array. @@ -24,9 +25,11 @@ * * @throws Psl\Exception\InvariantViolationException If the $n is negative * - * @psalm-pure + * @deprecated use `Dict\drop` instead. + * + * @see Dict\drop() */ -function drop(array $array, int $n): array +function drop(iterable $array, int $n): array { - return slice($array, $n); + return Dict\drop($array, $n); } diff --git a/src/Psl/Arr/drop_while.php b/src/Psl/Arr/drop_while.php index 509d8b6e1..983489c92 100644 --- a/src/Psl/Arr/drop_while.php +++ b/src/Psl/Arr/drop_while.php @@ -4,6 +4,8 @@ namespace Psl\Arr; +use Psl\Dict; + /** * Drops items from an iterable until the predicate fails for the first time. * @@ -22,20 +24,12 @@ * @psalm-param (callable(Tv): bool) $predicate * * @psalm-return array + * + * @deprecated use `Dict\drop_while` instead. + * + * @see Dict\drop_while() */ function drop_while(iterable $iterable, callable $predicate): array { - $result = []; - $failed = false; - foreach ($iterable as $key => $value) { - if (!$failed && !$predicate($value)) { - $failed = true; - } - - if ($failed) { - $result[$key] = $value; - } - } - - return $result; + return Dict\drop_while($iterable, $predicate); } diff --git a/src/Psl/Arr/equal.php b/src/Psl/Arr/equal.php index 32837437a..5ff650159 100644 --- a/src/Psl/Arr/equal.php +++ b/src/Psl/Arr/equal.php @@ -4,7 +4,7 @@ namespace Psl\Arr; -use Psl\Iter; +use Psl\Dict; /** * Returns whether the two given arrays have the same entries, using strict @@ -15,22 +15,12 @@ * * @psalm-param array $array * @psalm-param array $array2 + * + * @deprecated use `Dict\equal` instead. + * + * @see Dict\equal() */ function equal(array $array, array $array2): bool { - if ($array === $array2) { - return true; - } - - if (Iter\count($array) !== Iter\count($array2)) { - return false; - } - - foreach ($array as $key => $value) { - if (!contains_key($array2, $key) || $array2[$key] !== $value) { - return false; - } - } - - return true; + return Dict\equal($array, $array2); } diff --git a/src/Psl/Arr/filter.php b/src/Psl/Arr/filter.php index c9d615db3..94f9eea8b 100644 --- a/src/Psl/Arr/filter.php +++ b/src/Psl/Arr/filter.php @@ -4,7 +4,7 @@ namespace Psl\Arr; -use Closure; +use Psl\Dict; /** * Returns an array containing only the values for which the given predicate @@ -27,17 +27,12 @@ * @psalm-param (callable(Tv): bool)|null $predicate * * @psalm-return array + * + * @deprecated use `Dict\filter` instead. + * + * @see Dict\filter() */ function filter(iterable $iterable, ?callable $predicate = null): array { - /** @psalm-var (callable(Tv): bool) $predicate */ - $predicate = $predicate ?? Closure::fromCallable('Psl\Internal\boolean'); - $result = []; - foreach ($iterable as $k => $v) { - if ($predicate($v)) { - $result[$k] = $v; - } - } - - return $result; + return Dict\filter($iterable, $predicate); } diff --git a/src/Psl/Arr/filter_keys.php b/src/Psl/Arr/filter_keys.php index eac44e735..f9bd38d29 100644 --- a/src/Psl/Arr/filter_keys.php +++ b/src/Psl/Arr/filter_keys.php @@ -4,10 +4,10 @@ namespace Psl\Arr; -use Closure; +use Psl\Dict; /** - * Returns an array containing only the keys for which the given predicate + * Returns a dict containing only the keys for which the given predicate * returns `true`. * * The default predicate is casting the key to boolean. @@ -27,17 +27,12 @@ * @psalm-param (callable(Tk): bool)|null $predicate * * @psalm-return array + * + * @deprecated use `Dict\filter_keys` instead. + * + * @see Dict\filter_keys() */ function filter_keys(iterable $iterable, ?callable $predicate = null): array { - /** @psalm-var (callable(Tk): bool) $predicate */ - $predicate = $predicate ?? Closure::fromCallable('Psl\Internal\boolean'); - $result = []; - foreach ($iterable as $k => $v) { - if ($predicate($k)) { - $result[$k] = $v; - } - } - - return $result; + return Dict\filter_keys($iterable, $predicate); } diff --git a/src/Psl/Arr/filter_with_key.php b/src/Psl/Arr/filter_with_key.php index 7af331f57..5a23b93f1 100644 --- a/src/Psl/Arr/filter_with_key.php +++ b/src/Psl/Arr/filter_with_key.php @@ -4,7 +4,7 @@ namespace Psl\Arr; -use Psl; +use Psl\Dict; /** * Returns an array containing only the keys and values for which the given predicate @@ -30,23 +30,12 @@ * @psalm-param (callable(Tk, Tv): bool)|null $predicate * * @psalm-return array + * + * @deprecated use `Dict\filter_with_key` instead. + * + * @see Dict\filter_with_key() */ function filter_with_key(iterable $iterable, ?callable $predicate = null): array { - $predicate = $predicate ?? - /** - * @psalm-param Tk $k - * @psalm-param Tv $v - */ - static fn ($k, $v): bool => Psl\Internal\boolean($v); - - /** @psalm-var array $result */ - $result = []; - foreach ($iterable as $k => $v) { - if ($predicate($k, $v)) { - $result[$k] = $v; - } - } - - return $result; + return Dict\filter_with_key($iterable, $predicate); } diff --git a/src/Psl/Arr/flatten.php b/src/Psl/Arr/flatten.php index d29616c92..f67a38bab 100644 --- a/src/Psl/Arr/flatten.php +++ b/src/Psl/Arr/flatten.php @@ -4,6 +4,8 @@ namespace Psl\Arr; +use Psl\Dict; + /** * Returns a new array formed by merging the iterable elements of the * given iterable. @@ -24,15 +26,12 @@ * @psalm-param iterable> $iterables * * @psalm-return array + * + * @deprecated use `Dict\flatten` instead. + * + * @see Dict\flatten */ function flatten(iterable $iterables): array { - $result = []; - foreach ($iterables as $iterable) { - foreach ($iterable as $key => $value) { - $result[$key] = $value; - } - } - - return $result; + return Dict\flatten($iterables); } diff --git a/src/Psl/Arr/flip.php b/src/Psl/Arr/flip.php index 024b32321..0cb4a08a0 100644 --- a/src/Psl/Arr/flip.php +++ b/src/Psl/Arr/flip.php @@ -4,8 +4,7 @@ namespace Psl\Arr; -use Psl; -use Psl\Type; +use Psl\Dict; /** * Flips the keys and values of an array. In case of @@ -22,20 +21,12 @@ * @psalm-param array $array * * @psalm-return array + * + * @deprecated use `Dict\flip` instead. + * + * @see Dict\flip */ function flip(array $array): array { - $result = []; - foreach ($array as $k => $v) { - Psl\invariant( - Type\is_arraykey($v), - 'Expected all values to be of type array-key, value of type (%s) provided.', - gettype($v) - ); - - $result[$v] = $k; - } - - /** @psalm-var array $result*/ - return $result; + return Dict\flip($array); } diff --git a/src/Psl/Arr/group_by.php b/src/Psl/Arr/group_by.php index c780fabb1..0d5f2b019 100644 --- a/src/Psl/Arr/group_by.php +++ b/src/Psl/Arr/group_by.php @@ -4,8 +4,7 @@ namespace Psl\Arr; -use Psl; -use Psl\Type; +use Psl\Dict; /** * Returns a new array where @@ -37,25 +36,12 @@ * @psalm-param (callable(Tv): ?Tk) $key_func * * @psalm-return array> + * + * @deprecated use Dict\group_by + * + * @see Dict\group_by */ function group_by(iterable $values, callable $key_func): array { - $result = []; - foreach ($values as $value) { - $key = $key_func($value); - if (null === $key) { - continue; - } - - Psl\invariant( - Type\is_arraykey($key), - 'Expected $key_func to return a value of type array-key, value of type (%s) returned.', - gettype($key) - ); - /** @psalm-var Tk $key */ - $result[$key] = $result[$key] ?? []; - $result[$key][] = $value; - } - - return $result; + return Dict\group_by($values, $key_func); } diff --git a/src/Psl/Arr/keys.php b/src/Psl/Arr/keys.php index 24d16e819..06a7c6251 100644 --- a/src/Psl/Arr/keys.php +++ b/src/Psl/Arr/keys.php @@ -17,6 +17,8 @@ * @psalm-return list * * @deprecated since 1.2, use Vec\keys instead. + * + * @see Vec\keys() */ function keys(array $arr): array { diff --git a/src/Psl/Arr/map.php b/src/Psl/Arr/map.php index f451ea3a2..f1eefe4e3 100644 --- a/src/Psl/Arr/map.php +++ b/src/Psl/Arr/map.php @@ -4,6 +4,8 @@ namespace Psl\Arr; +use Psl\Dict; + /** * Applies a mapping function to all values of an iterable. * @@ -25,13 +27,12 @@ * @psalm-param (callable(Tv): T) $function * * @psalm-return array + * + * @deprecated use `Dict\map` instead. + * + * @see Dict\map() */ function map(iterable $iterable, callable $function): array { - $result = []; - foreach ($iterable as $key => $value) { - $result[$key] = $function($value); - } - - return $result; + return Dict\map($iterable, $function); } diff --git a/src/Psl/Arr/map_keys.php b/src/Psl/Arr/map_keys.php index 2026bf124..19913e558 100644 --- a/src/Psl/Arr/map_keys.php +++ b/src/Psl/Arr/map_keys.php @@ -4,6 +4,8 @@ namespace Psl\Arr; +use Psl\Dict; + /** * Applies a mapping function to all keys of an iterable. * @@ -25,13 +27,12 @@ * @psalm-param (callable(Tk1): Tk2) $function * * @psalm-return array + * + * @deprecated use `Dict\map_keys` instead. + * + * @see Dict\map() */ function map_keys(iterable $iterable, callable $function): array { - $result = []; - foreach ($iterable as $key => $value) { - $result[$function($key)] = $value; - } - - return $result; + return Dict\map_keys($iterable, $function); } diff --git a/src/Psl/Arr/map_with_key.php b/src/Psl/Arr/map_with_key.php index c42697567..9bd1f4965 100644 --- a/src/Psl/Arr/map_with_key.php +++ b/src/Psl/Arr/map_with_key.php @@ -4,6 +4,8 @@ namespace Psl\Arr; +use Psl\Dict; + /** * Applies a mapping function to all values of an iterable. * @@ -25,13 +27,12 @@ * @psalm-param (callable(Tk,Tv): T) $function * * @psalm-return array + * + * @deprecated use `Dict\map_with_key` instead. + * + * @see Dict\map_with_key() */ function map_with_key(iterable $iterable, callable $function): array { - $result = []; - foreach ($iterable as $key => $value) { - $result[$key] = $function($key, $value); - } - - return $result; + return Dict\map_with_key($iterable, $function); } diff --git a/src/Psl/Arr/merge.php b/src/Psl/Arr/merge.php index 56da911c0..d57d3b852 100644 --- a/src/Psl/Arr/merge.php +++ b/src/Psl/Arr/merge.php @@ -4,6 +4,8 @@ namespace Psl\Arr; +use Psl\Dict; + /** * Merges multiple iterables into a new array. * @@ -23,11 +25,15 @@ * @psalm-param iterable ...$rest * * @psalm-return array + * + * @deprecated use `Dict\merge` instead. + * + * @see Dict\merge() */ function merge(iterable $first, iterable ...$rest): array { - /** @psalm-var list> $arrays */ - $arrays = [$first, ...$rest]; + /** @psalm-var list> $iterables */ + $iterables = [$first, ...$rest]; - return flatten($arrays); + return Dict\flatten($iterables); } diff --git a/src/Psl/Arr/partition.php b/src/Psl/Arr/partition.php index 0151f95f7..1cb96fd7a 100644 --- a/src/Psl/Arr/partition.php +++ b/src/Psl/Arr/partition.php @@ -4,6 +4,8 @@ namespace Psl\Arr; +use Psl\Vec; + /** * Return a 2-elements array for which the given predicate returned `true` and `false`, respectively. * @@ -13,18 +15,12 @@ * @psalm-param (callable(T): bool) $predicate * * @psalm-return array{0: list, 1: list} + * + * @deprecated use `Vec\partition` instead. + * + * @see Vec\partition */ function partition(iterable $list, callable $predicate): array { - $success = []; - $failure = []; - foreach ($list as $value) { - if ($predicate($value)) { - $success[] = $value; - } else { - $failure[] = $value; - } - } - - return [$success, $failure]; + return Vec\partition($list, $predicate); } diff --git a/src/Psl/Arr/select_keys.php b/src/Psl/Arr/select_keys.php index 4936e77b4..8d5cdd69e 100644 --- a/src/Psl/Arr/select_keys.php +++ b/src/Psl/Arr/select_keys.php @@ -4,6 +4,8 @@ namespace Psl\Arr; +use Psl\Dict; + /** * Returns a new array containing only the keys found in both the input array * and the given list. The array will have the same ordering as the @@ -17,16 +19,11 @@ * * @psalm-return array * - * @psalm-pure + * @deprecated use `Dict\select_keys` instead. + * + * @see Dict\select_keys */ function select_keys(array $array, array $keys): array { - $result = []; - foreach ($keys as $key) { - if (contains_key($array, $key)) { - $result[$key] = $array[$key]; - } - } - - return $result; + return Dict\select_keys($array, $keys); } diff --git a/src/Psl/Arr/slice.php b/src/Psl/Arr/slice.php index fbc816f12..9487c7d03 100644 --- a/src/Psl/Arr/slice.php +++ b/src/Psl/Arr/slice.php @@ -5,6 +5,7 @@ namespace Psl\Arr; use Psl; +use Psl\Dict; /** * Takes a slice from an array. @@ -28,29 +29,11 @@ * * @throws Psl\Exception\InvariantViolationException If the $start offset or $length are negative * - * @psalm-pure + * @deprecated use `Dict\slice()` instead. + * + * @see Dict\slice() */ function slice(array $array, int $start, ?int $length = null): array { - Psl\invariant($start >= 0, 'Start offset must be non-negative.'); - Psl\invariant(null === $length || $length >= 0, 'Length must be non-negative.'); - - $result = []; - if (0 === $length) { - return $result; - } - - $i = 0; - foreach ($array as $key => $value) { - if ($i++ < $start) { - continue; - } - - $result[$key] = $value; - if (null !== $length && $i >= $start + $length) { - break; - } - } - - return $result; + return Dict\slice($array, $start, $length); } diff --git a/src/Psl/Arr/sort_by_key.php b/src/Psl/Arr/sort_by_key.php index 7475e4871..62e6d3b6d 100644 --- a/src/Psl/Arr/sort_by_key.php +++ b/src/Psl/Arr/sort_by_key.php @@ -4,8 +4,7 @@ namespace Psl\Arr; -use function ksort; -use function uksort; +use Psl\Dict; /** * Returns a new array sorted by the keys of the given array. If the @@ -19,14 +18,12 @@ * @psalm-param (callable(Tk, Tk): int)|null $comparator * * @psalm-return array + * + * @deprecated use `Dict\sort_by_key` + * + * @use Dict\sort_by_key */ function sort_by_key(array $array, ?callable $comparator = null): array { - if ($comparator) { - uksort($array, $comparator); - } else { - ksort($array); - } - - return $array; + return Dict\sort_by_key($array, $comparator); } diff --git a/src/Psl/Arr/sort_with_keys.php b/src/Psl/Arr/sort_with_keys.php index dfab8dd33..0fac169b2 100644 --- a/src/Psl/Arr/sort_with_keys.php +++ b/src/Psl/Arr/sort_with_keys.php @@ -4,8 +4,7 @@ namespace Psl\Arr; -use function asort; -use function uasort; +use Psl\Dict; /** * Returns a new array sorted by the values of the given array. If the @@ -19,14 +18,12 @@ * @psalm-param (callable(Tv, Tv): int)|null $comparator * * @psalm-return array + * + * @deprecated use `Dict\sort` instead + * + * @see Dict\sort() */ function sort_with_keys(array $array, ?callable $comparator = null): array { - if (null !== $comparator) { - uasort($array, $comparator); - } else { - asort($array); - } - - return $array; + return Dict\sort($array, $comparator); } diff --git a/src/Psl/Arr/sort_with_keys_by.php b/src/Psl/Arr/sort_with_keys_by.php index c922410b9..42e558522 100644 --- a/src/Psl/Arr/sort_with_keys_by.php +++ b/src/Psl/Arr/sort_with_keys_by.php @@ -4,6 +4,8 @@ namespace Psl\Arr; +use Psl\Dict; + /** * Returns a new array sorted by some scalar property of each value of the given * iterable, which is computed by the given function. @@ -20,41 +22,12 @@ * @psalm-param (callable(Ts, Ts): int)|null $comparator * * @psalm-return array + * + * @deprecated use `Dict\sort_by` instead + * + * @see Dict\sort_by() */ function sort_with_keys_by(iterable $iterable, callable $scalar_func, ?callable $comparator = null): array { - $comparator ??= - /** - * @psalm-param Ts $a - * @psalm-param Ts $b - */ - static fn ($a, $b): int => $a <=> $b; - - $tuple_comparator = - /** - * @psalm-param array{0: Ts, 1: Tv} $a - * @psalm-param array{0: Ts, 1: Tv} $b - */ - static fn ($a, $b): int => $comparator($a[0], $b[0]); - - /** - * @psalm-var array $tuples - */ - $tuples = []; - foreach ($iterable as $k => $v) { - $tuples[$k] = [$scalar_func($v), $v]; - } - - /** - * @psalm-var array $sorted - */ - $sorted = sort_with_keys($tuples, $tuple_comparator); - - /** @psalm-var array $result */ - $result = []; - foreach ($sorted as $k => $v) { - $result[$k] = $v[1]; - } - - return $result; + return Dict\sort_by($iterable, $scalar_func, $comparator); } diff --git a/src/Psl/Arr/take.php b/src/Psl/Arr/take.php index 2ab9703f9..c97a98588 100644 --- a/src/Psl/Arr/take.php +++ b/src/Psl/Arr/take.php @@ -5,6 +5,7 @@ namespace Psl\Arr; use Psl; +use Psl\Dict; /** * Take the first n elements from an array. @@ -18,9 +19,11 @@ * * @throws Psl\Exception\InvariantViolationException If the $n is negative * - * @psalm-pure + * @deprecated use `Dict\take` instead. + * + * @see Dict\take() */ -function take(array $array, int $n): array +function take(iterable $array, int $n): array { - return slice($array, 0, $n); + return Dict\take($array, $n); } diff --git a/src/Psl/Arr/take_while.php b/src/Psl/Arr/take_while.php index 92772923d..dd55bbf00 100644 --- a/src/Psl/Arr/take_while.php +++ b/src/Psl/Arr/take_while.php @@ -4,6 +4,8 @@ namespace Psl\Arr; +use Psl\Dict; + /** * Takes items from an iterable until the predicate fails for the first time. * @@ -22,18 +24,12 @@ * @psalm-param (callable(Tv): bool) $predicate * * @psalm-return array + * + * @deprecated use `Dict\take_while` instead. + * + * @see Dict\take_while() */ function take_while(iterable $iterable, callable $predicate): array { - $result = []; - foreach ($iterable as $key => $value) { - if (!$predicate($value)) { - return $result; - } - - $result[$key] = $value; - } - - - return $result; + return Dict\take_while($iterable, $predicate); } diff --git a/src/Psl/Arr/unique.php b/src/Psl/Arr/unique.php index e7b8b007e..4f8207212 100644 --- a/src/Psl/Arr/unique.php +++ b/src/Psl/Arr/unique.php @@ -4,6 +4,8 @@ namespace Psl\Arr; +use Psl\Dict; + /** * Returns a new array in which each value appears exactly once. * @@ -13,18 +15,12 @@ * @psalm-param iterable $iterable * * @psalm-return array + * + * @deprecated use `Dict\unique` instead + * + * @see Dict\unique */ function unique(iterable $iterable): array { - return unique_by( - $iterable, - /** - * @psalm-param Tv $v - * - * @psalm-return Tv - * - * @psalm-pure - */ - static fn($v) => $v - ); + return Dict\unique($iterable); } diff --git a/src/Psl/Arr/unique_by.php b/src/Psl/Arr/unique_by.php index 73ca59cfa..99d42826e 100644 --- a/src/Psl/Arr/unique_by.php +++ b/src/Psl/Arr/unique_by.php @@ -4,6 +4,8 @@ namespace Psl\Arr; +use Psl\Dict; + /** * Returns a new array in which each value appears exactly once, where the * value's uniqueness is determined by transforming it to a scalar via the @@ -17,28 +19,12 @@ * @psalm-param (callable(Tv): Ts) $scalar_func * * @psalm-return array + * + * @deprecated use `Dict\unique_by` instead + * + * @see Dict\unique_by */ function unique_by(iterable $iterable, callable $scalar_func): array { - /** @psalm-var array $unique */ - $unique = []; - /** @psalm-var array $original_values */ - $original_values = []; - foreach ($iterable as $k => $v) { - $original_values[$k] = $v; - /** @psalm-var Ts $scalar */ - $scalar = $scalar_func($v); - - if (!contains($unique, $scalar)) { - $unique[$k] = $scalar; - } - } - - /** @psalm-var array $result */ - $result = []; - foreach ($unique as $k => $_) { - $result[$k] = $original_values[$k]; - } - - return $result; + return Dict\unique_by($iterable, $scalar_func); } diff --git a/src/Psl/Collection/Map.php b/src/Psl/Collection/Map.php index ae0938549..8f51a55d3 100644 --- a/src/Psl/Collection/Map.php +++ b/src/Psl/Collection/Map.php @@ -6,6 +6,7 @@ use Psl; use Psl\Arr; +use Psl\Dict; use Psl\Iter; use Psl\Vec; @@ -31,7 +32,7 @@ final class Map implements MapInterface */ public function __construct(iterable $elements) { - $this->elements = Iter\to_array_with_keys($elements); + $this->elements = Dict\from_iterable($elements); } /** @@ -221,7 +222,7 @@ public function keys(): Vector */ public function filter(callable $fn): Map { - return new Map(Arr\filter($this->elements, $fn)); + return new Map(Dict\filter($this->elements, $fn)); } /** @@ -244,7 +245,7 @@ public function filter(callable $fn): Map */ public function filterWithKey(callable $fn): Map { - return new Map(Arr\filter_with_key($this->elements, $fn)); + return new Map(Dict\filter_with_key($this->elements, $fn)); } /** @@ -267,7 +268,7 @@ public function filterWithKey(callable $fn): Map */ public function map(callable $fn): Map { - return new Map(Iter\map($this->elements, $fn)); + return new Map(Dict\map($this->elements, $fn)); } /** @@ -292,7 +293,7 @@ public function map(callable $fn): Map */ public function mapWithKey(callable $fn): Map { - return new Map(Iter\map_with_key($this->elements, $fn)); + return new Map(Dict\map_with_key($this->elements, $fn)); } /** @@ -314,18 +315,20 @@ public function mapWithKey(callable $fn): Map */ public function zip(iterable $iterable): Map { + $array = Vec\values($iterable); + /** @psalm-var array $elements */ $elements = []; foreach ($this->elements as $k => $v) { /** @psalm-var Tu|null $u */ - $u = Iter\first($iterable); + $u = Iter\first($array); if (null === $u) { break; } - /** @psalm-var iterable $iterable */ - $iterable = Iter\drop($iterable, 1); + /** @psalm-var iterable $array */ + $array = Dict\drop($array, 1); $elements[$k] = [$v, $u]; } @@ -352,7 +355,7 @@ public function zip(iterable $iterable): Map */ public function take(int $n): Map { - return new Map(Arr\take($this->elements, $n)); + return new Map(Dict\take($this->elements, $n)); } /** @@ -371,7 +374,7 @@ public function take(int $n): Map */ public function takeWhile(callable $fn): Map { - return new Map(Arr\take_while($this->elements, $fn)); + return new Map(Dict\take_while($this->elements, $fn)); } /** @@ -393,7 +396,7 @@ public function takeWhile(callable $fn): Map */ public function drop(int $n): Map { - return new Map(Arr\drop($this->elements, $n)); + return new Map(Dict\drop($this->elements, $n)); } /** @@ -412,7 +415,7 @@ public function drop(int $n): Map */ public function dropWhile(callable $fn): Map { - return new Map(Arr\drop_while($this->elements, $fn)); + return new Map(Dict\drop_while($this->elements, $fn)); } /** @@ -438,6 +441,6 @@ public function dropWhile(callable $fn): Map */ public function slice(int $start, int $len): Map { - return new Map(Arr\slice($this->elements, $start, $len)); + return new Map(Dict\slice($this->elements, $start, $len)); } } diff --git a/src/Psl/Collection/MutableMap.php b/src/Psl/Collection/MutableMap.php index c6f287671..c34a00cd7 100644 --- a/src/Psl/Collection/MutableMap.php +++ b/src/Psl/Collection/MutableMap.php @@ -6,6 +6,7 @@ use Psl; use Psl\Arr; +use Psl\Dict; use Psl\Iter; use Psl\Vec; @@ -29,7 +30,7 @@ final class MutableMap implements MutableMapInterface */ public function __construct(iterable $elements) { - $this->elements = Iter\to_array_with_keys($elements); + $this->elements = Dict\from_iterable($elements); } /** @@ -218,7 +219,7 @@ public function keys(): MutableVector */ public function filter(callable $fn): MutableMap { - return new MutableMap(Arr\filter($this->elements, $fn)); + return new MutableMap(Dict\filter($this->elements, $fn)); } /** @@ -241,7 +242,7 @@ public function filter(callable $fn): MutableMap */ public function filterWithKey(callable $fn): MutableMap { - return new MutableMap(Arr\filter_with_key($this->elements, $fn)); + return new MutableMap(Dict\filter_with_key($this->elements, $fn)); } /** @@ -264,7 +265,7 @@ public function filterWithKey(callable $fn): MutableMap */ public function map(callable $fn): MutableMap { - return new MutableMap(Iter\map($this->elements, $fn)); + return new MutableMap(Dict\map($this->elements, $fn)); } /** @@ -289,7 +290,7 @@ public function map(callable $fn): MutableMap */ public function mapWithKey(callable $fn): MutableMap { - return new MutableMap(Iter\map_with_key($this->elements, $fn)); + return new MutableMap(Dict\map_with_key($this->elements, $fn)); } /** @@ -311,18 +312,18 @@ public function mapWithKey(callable $fn): MutableMap */ public function zip(iterable $iterable): MutableMap { + $array = Vec\values($iterable); /** @psalm-var array $elements */ $elements = []; foreach ($this->elements as $k => $v) { /** @psalm-var Tu|null $u */ - $u = Iter\first($iterable); + $u = Iter\first($array); if (null === $u) { break; } - /** @psalm-var iterable $iterable */ - $iterable = Iter\drop($iterable, 1); + $array = Dict\drop($array, 1); $elements[$k] = [$v, $u]; } @@ -349,7 +350,7 @@ public function zip(iterable $iterable): MutableMap */ public function take(int $n): MutableMap { - return new MutableMap(Arr\take($this->elements, $n)); + return new MutableMap(Dict\take($this->elements, $n)); } /** @@ -368,7 +369,7 @@ public function take(int $n): MutableMap */ public function takeWhile(callable $fn): MutableMap { - return new MutableMap(Arr\take_while($this->elements, $fn)); + return new MutableMap(Dict\take_while($this->elements, $fn)); } /** @@ -391,7 +392,7 @@ public function takeWhile(callable $fn): MutableMap */ public function drop(int $n): MutableMap { - return new MutableMap(Arr\drop($this->elements, $n)); + return new MutableMap(Dict\drop($this->elements, $n)); } /** @@ -410,7 +411,7 @@ public function drop(int $n): MutableMap */ public function dropWhile(callable $fn): MutableMap { - return new MutableMap(Arr\drop_while($this->elements, $fn)); + return new MutableMap(Dict\drop_while($this->elements, $fn)); } /** @@ -436,7 +437,7 @@ public function dropWhile(callable $fn): MutableMap */ public function slice(int $start, int $len): MutableMap { - return new MutableMap(Arr\slice($this->elements, $start, $len)); + return new MutableMap(Dict\slice($this->elements, $start, $len)); } /** diff --git a/src/Psl/Collection/MutableVector.php b/src/Psl/Collection/MutableVector.php index 9fd2e1f8b..aaf17d7a2 100644 --- a/src/Psl/Collection/MutableVector.php +++ b/src/Psl/Collection/MutableVector.php @@ -6,6 +6,7 @@ use Psl; use Psl\Arr; +use Psl\Dict; use Psl\Iter; use Psl\Vec; @@ -341,7 +342,7 @@ public function keys(): MutableVector */ public function filter(callable $fn): MutableVector { - return new MutableVector(Arr\filter($this->elements, $fn)); + return new MutableVector(Dict\filter($this->elements, $fn)); } /** @@ -364,7 +365,7 @@ public function filter(callable $fn): MutableVector */ public function filterWithKey(callable $fn): MutableVector { - return new MutableVector(Arr\filter_with_key($this->elements, $fn)); + return new MutableVector(Dict\filter_with_key($this->elements, $fn)); } /** @@ -387,7 +388,7 @@ public function filterWithKey(callable $fn): MutableVector */ public function map(callable $fn): MutableVector { - return new MutableVector(Iter\map($this->elements, $fn)); + return new MutableVector(Dict\map($this->elements, $fn)); } /** @@ -412,7 +413,7 @@ public function map(callable $fn): MutableVector */ public function mapWithKey(callable $fn): MutableVector { - return new MutableVector(Iter\map_with_key($this->elements, $fn)); + return new MutableVector(Dict\map_with_key($this->elements, $fn)); } /** @@ -456,7 +457,7 @@ public function zip(iterable $iterable): MutableVector */ public function take(int $n): MutableVector { - return new MutableVector(Arr\take($this->elements, $n)); + return new MutableVector(Dict\take($this->elements, $n)); } /** @@ -475,7 +476,7 @@ public function take(int $n): MutableVector */ public function takeWhile(callable $fn): MutableVector { - return new MutableVector(Arr\take_while($this->elements, $fn)); + return new MutableVector(Dict\take_while($this->elements, $fn)); } /** @@ -498,7 +499,7 @@ public function takeWhile(callable $fn): MutableVector */ public function drop(int $n): MutableVector { - return new MutableVector(Arr\drop($this->elements, $n)); + return new MutableVector(Dict\drop($this->elements, $n)); } /** @@ -517,7 +518,7 @@ public function drop(int $n): MutableVector */ public function dropWhile(callable $fn): MutableVector { - return new MutableVector(Arr\drop_while($this->elements, $fn)); + return new MutableVector(Dict\drop_while($this->elements, $fn)); } /** @@ -543,6 +544,6 @@ public function dropWhile(callable $fn): MutableVector */ public function slice(int $start, int $len): MutableVector { - return new MutableVector(Arr\slice($this->elements, $start, $len)); + return new MutableVector(Dict\slice($this->elements, $start, $len)); } } diff --git a/src/Psl/Collection/Vector.php b/src/Psl/Collection/Vector.php index 61d9ffafb..f2010d0b3 100644 --- a/src/Psl/Collection/Vector.php +++ b/src/Psl/Collection/Vector.php @@ -6,6 +6,7 @@ use Psl; use Psl\Arr; +use Psl\Dict; use Psl\Iter; use Psl\Vec; @@ -225,7 +226,7 @@ public function keys(): Vector */ public function filter(callable $fn): Vector { - return new Vector(Arr\filter($this->elements, $fn)); + return new Vector(Dict\filter($this->elements, $fn)); } /** @@ -248,7 +249,7 @@ public function filter(callable $fn): Vector */ public function filterWithKey(callable $fn): Vector { - return new Vector(Arr\filter_with_key($this->elements, $fn)); + return new Vector(Dict\filter_with_key($this->elements, $fn)); } /** @@ -271,7 +272,7 @@ public function filterWithKey(callable $fn): Vector */ public function map(callable $fn): Vector { - return new Vector(Iter\map($this->elements, $fn)); + return new Vector(Dict\map($this->elements, $fn)); } /** @@ -296,7 +297,7 @@ public function map(callable $fn): Vector */ public function mapWithKey(callable $fn): Vector { - return new Vector(Iter\map_with_key($this->elements, $fn)); + return new Vector(Dict\map_with_key($this->elements, $fn)); } /** @@ -340,7 +341,7 @@ public function zip(iterable $iterable): Vector */ public function take(int $n): Vector { - return new Vector(Arr\take($this->elements, $n)); + return new Vector(Dict\take($this->elements, $n)); } /** @@ -359,7 +360,7 @@ public function take(int $n): Vector */ public function takeWhile(callable $fn): Vector { - return new Vector(Arr\take_while($this->elements, $fn)); + return new Vector(Dict\take_while($this->elements, $fn)); } /** @@ -382,7 +383,7 @@ public function takeWhile(callable $fn): Vector */ public function drop(int $n): Vector { - return new Vector(Arr\drop($this->elements, $n)); + return new Vector(Dict\drop($this->elements, $n)); } /** @@ -401,7 +402,7 @@ public function drop(int $n): Vector */ public function dropWhile(callable $fn): Vector { - return new Vector(Arr\drop_while($this->elements, $fn)); + return new Vector(Dict\drop_while($this->elements, $fn)); } /** @@ -427,6 +428,6 @@ public function dropWhile(callable $fn): Vector */ public function slice(int $start, int $len): Vector { - return new Vector(Arr\slice($this->elements, $start, $len)); + return new Vector(Dict\slice($this->elements, $start, $len)); } } diff --git a/src/Psl/DataStructure/PriorityQueue.php b/src/Psl/DataStructure/PriorityQueue.php index de12b5d31..6ef88748d 100644 --- a/src/Psl/DataStructure/PriorityQueue.php +++ b/src/Psl/DataStructure/PriorityQueue.php @@ -6,6 +6,7 @@ use Psl; use Psl\Arr; +use Psl\Dict; use Psl\Iter; use Psl\Math; use Psl\Vec; @@ -125,7 +126,7 @@ private function drop(): void * * @psalm-suppress MissingThrowsDocblock */ - $this->queue[$priority] = Vec\values(Arr\drop($nodes, 1)); + $this->queue[$priority] = Vec\values(Dict\drop($nodes, 1)); } } diff --git a/src/Psl/DataStructure/Queue.php b/src/Psl/DataStructure/Queue.php index f3ffec125..689aa16fe 100644 --- a/src/Psl/DataStructure/Queue.php +++ b/src/Psl/DataStructure/Queue.php @@ -6,6 +6,7 @@ use Psl; use Psl\Arr; +use Psl\Dict; use Psl\Iter; use Psl\Vec; @@ -72,7 +73,7 @@ public function dequeue() Psl\invariant(0 !== $this->count(), 'Cannot dequeue a node from an empty Queue.'); $node = Arr\firstx($this->queue); - $this->queue = Vec\values(Arr\drop($this->queue, 1)); + $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 f235c6d4f..a1aaccbc6 100644 --- a/src/Psl/DataStructure/Stack.php +++ b/src/Psl/DataStructure/Stack.php @@ -6,6 +6,7 @@ use Psl; use Psl\Arr; +use Psl\Dict; use Psl\Iter; use Psl\Vec; @@ -72,7 +73,7 @@ public function pop() Psl\invariant(0 !== $this->count(), 'Cannot pop an item from an empty Stack.'); $tail = Arr\lastx($this->items); - $this->items = Vec\values(Arr\take($this->items, $this->count() - 1)); + $this->items = Vec\values(Dict\take($this->items, $this->count() - 1)); return $tail; } diff --git a/src/Psl/Dict/associate.php b/src/Psl/Dict/associate.php new file mode 100644 index 000000000..9c806bfc5 --- /dev/null +++ b/src/Psl/Dict/associate.php @@ -0,0 +1,40 @@ + $keys + * @param iterable $values + * + * @return array + * + * @throws Psl\Exception\InvariantViolationException If $keys and $values have different length. + */ +function associate(iterable $keys, iterable $values): array +{ + $key_vec = Vec\values($keys); + $value_vec = Vec\values($values); + + Psl\invariant( + Iter\count($key_vec) === Iter\count($value_vec), + 'Expected length of $keys and $values to be the same', + ); + + $result = []; + foreach ($key_vec as $i => $key) { + $result[$key] = $value_vec[$i]; + } + return $result; +} diff --git a/src/Psl/Dict/drop.php b/src/Psl/Dict/drop.php new file mode 100644 index 000000000..dcfe9f4c2 --- /dev/null +++ b/src/Psl/Dict/drop.php @@ -0,0 +1,30 @@ + Dict(4, 5) + * + * @psalm-template Tk of array-key + * @psalm-template Tv + * + * @psalm-param iterable $iterable Iterable to drop the elements from + * @psalm-param int $n Number of elements to drop from the start + * + * @psalm-return array + * + * @throws Psl\Exception\InvariantViolationException If the $n is negative + */ +function drop(iterable $iterable, int $n): array +{ + return slice($iterable, $n); +} diff --git a/src/Psl/Dict/drop_while.php b/src/Psl/Dict/drop_while.php new file mode 100644 index 000000000..195ff0a73 --- /dev/null +++ b/src/Psl/Dict/drop_while.php @@ -0,0 +1,41 @@ + $i > 0) + * => Dict(-1, 5) + * + * @psalm-template Tk of array-key + * @psalm-template Tv + * + * @psalm-param iterable $iterable Iterable to drop values from + * @psalm-param (callable(Tv): bool) $predicate + * + * @psalm-return array + */ +function drop_while(iterable $iterable, callable $predicate): array +{ + $result = []; + $failed = false; + foreach ($iterable as $key => $value) { + if (!$failed && !$predicate($value)) { + $failed = true; + } + + if ($failed) { + $result[$key] = $value; + } + } + + return $result; +} diff --git a/src/Psl/Dict/equal.php b/src/Psl/Dict/equal.php new file mode 100644 index 000000000..de90d7f58 --- /dev/null +++ b/src/Psl/Dict/equal.php @@ -0,0 +1,37 @@ + $first + * @param array $second + */ +function equal(array $first, array $second): bool +{ + if ($first === $second) { + return true; + } + + if (Iter\count($first) !== Iter\count($second)) { + return false; + } + + foreach ($first as $k => $v) { + if (!Arr\contains_key($second, $k) || $second[$k] !== $v) { + return false; + } + } + + return true; +} diff --git a/src/Psl/Dict/filter.php b/src/Psl/Dict/filter.php new file mode 100644 index 000000000..fd5273b89 --- /dev/null +++ b/src/Psl/Dict/filter.php @@ -0,0 +1,43 @@ + Arr('a', 'b') + * + * Arr\filter(['foo', 'bar', 'baz', 'qux'], fn(string $value): bool => Str\contains($value, 'a')); + * => Arr('bar', 'baz') + * + * @psalm-template Tk of array-key + * @psalm-template Tv + * + * @psalm-param iterable $iterable + * @psalm-param (callable(Tv): bool)|null $predicate + * + * @psalm-return array + */ +function filter(iterable $iterable, ?callable $predicate = null): array +{ + /** @psalm-var (callable(Tv): bool) $predicate */ + $predicate = $predicate ?? Closure::fromCallable('Psl\Internal\boolean'); + $result = []; + foreach ($iterable as $k => $v) { + if ($predicate($v)) { + $result[$k] = $v; + } + } + + return $result; +} diff --git a/src/Psl/Dict/filter_keys.php b/src/Psl/Dict/filter_keys.php new file mode 100644 index 000000000..9bd373e9b --- /dev/null +++ b/src/Psl/Dict/filter_keys.php @@ -0,0 +1,43 @@ + 'a', 1 => 'b']) + * => Arr(1 => 'b') + * + * Arr\filter_keys([0 => 'a', 1 => 'b', 2 => 'c'], fn(int $key): bool => $key <= 1); + * => Arr(0 => 'a', 1 => 'b') + * + * @psalm-template Tk of array-key + * @psalm-template Tv + * + * @psalm-param iterable $iterable + * @psalm-param (callable(Tk): bool)|null $predicate + * + * @psalm-return array + */ +function filter_keys(iterable $iterable, ?callable $predicate = null): array +{ + /** @psalm-var (callable(Tk): bool) $predicate */ + $predicate = $predicate ?? Closure::fromCallable('Psl\Internal\boolean'); + $result = []; + foreach ($iterable as $k => $v) { + if ($predicate($k)) { + $result[$k] = $v; + } + } + + return $result; +} diff --git a/src/Psl/Dict/filter_with_key.php b/src/Psl/Dict/filter_with_key.php new file mode 100644 index 000000000..6148e14d9 --- /dev/null +++ b/src/Psl/Dict/filter_with_key.php @@ -0,0 +1,52 @@ + Iter('b', 'c') + * + * Arr\filter_with_key( + * ['foo', 'bar', 'baz', 'qux'], + * fn(int $key, string $value): bool => $key > 1 && Str\contains($value, 'a') + * ); + * => Arr('baz') + * + * @psalm-template Tk of array-key + * @psalm-template Tv + * + * @psalm-param iterable $iterable + * @psalm-param (callable(Tk, Tv): bool)|null $predicate + * + * @psalm-return array + */ +function filter_with_key(iterable $iterable, ?callable $predicate = null): array +{ + $predicate = $predicate ?? + /** + * @psalm-param Tk $k + * @psalm-param Tv $v + */ + static fn ($k, $v): bool => Psl\Internal\boolean($v); + + /** @psalm-var array $result */ + $result = []; + foreach ($iterable as $k => $v) { + if ($predicate($k, $v)) { + $result[$k] = $v; + } + } + + return $result; +} diff --git a/src/Psl/Dict/flatten.php b/src/Psl/Dict/flatten.php new file mode 100644 index 000000000..ad048d146 --- /dev/null +++ b/src/Psl/Dict/flatten.php @@ -0,0 +1,38 @@ + Dict(0 => 9, 1 => 8) + * + * Dict\flatten([[0 => 1, 1 => 2], [2 => 9, 3 => 8]]) + * => Dict(0 => 1, 1 => 2, 2 => 9, 3 => 8) + * + * @psalm-template Tk of array-key + * @psalm-template Tv + * + * @psalm-param iterable> $iterables + * + * @psalm-return array + */ +function flatten(iterable $iterables): array +{ + $result = []; + foreach ($iterables as $iterable) { + foreach ($iterable as $key => $value) { + $result[$key] = $value; + } + } + + return $result; +} diff --git a/src/Psl/Dict/flip.php b/src/Psl/Dict/flip.php new file mode 100644 index 000000000..3b357ecf7 --- /dev/null +++ b/src/Psl/Dict/flip.php @@ -0,0 +1,42 @@ + 1, 'b' => 2, 'c' => 3]) + * => Dict(1 => 'a', 2 => 'b', 3 => 'c') + * + * @psalm-template Tk of array-key + * @psalm-template Tv of array-key + * + * @psalm-param iterable $iterable + * + * @psalm-return array + */ +function flip(iterable $iterable): array +{ + $result = []; + foreach ($iterable as $key => $value) { + Psl\invariant( + Type\is_arraykey($value), + 'Expected all values to be of type array-key, value of type (%s) provided.', + gettype($value) + ); + + /** @var Tv $value */ + $result[$value] = $key; + } + + return $result; +} diff --git a/src/Psl/Dict/from_entries.php b/src/Psl/Dict/from_entries.php new file mode 100644 index 000000000..54e9b2766 --- /dev/null +++ b/src/Psl/Dict/from_entries.php @@ -0,0 +1,26 @@ + $entries + * + * @psalm-return array + */ +function from_entries(iterable $entries): array +{ + $result = []; + foreach ($entries as [$key, $value]) { + $result[$key] = $value; + } + + return $result; +} diff --git a/src/Psl/Dict/from_iterable.php b/src/Psl/Dict/from_iterable.php new file mode 100644 index 000000000..3dad336bc --- /dev/null +++ b/src/Psl/Dict/from_iterable.php @@ -0,0 +1,25 @@ + $iterable + * + * @psalm-return array + */ +function from_iterable(iterable $iterable): array +{ + $result = []; + foreach ($iterable as $key => $value) { + $result[$key] = $value; + } + + return $result; +} diff --git a/src/Psl/Dict/from_keys.php b/src/Psl/Dict/from_keys.php new file mode 100644 index 000000000..5de63361e --- /dev/null +++ b/src/Psl/Dict/from_keys.php @@ -0,0 +1,27 @@ + $keys + * @psalm-param (callable(Tk): Tv) $value_func + * + * @psalm-return array + */ +function from_keys(iterable $keys, callable $value_func): array +{ + $result = []; + foreach ($keys as $key) { + $result[$key] = $value_func($key); + } + + return $result; +} diff --git a/src/Psl/Dict/group_by.php b/src/Psl/Dict/group_by.php new file mode 100644 index 000000000..369409531 --- /dev/null +++ b/src/Psl/Dict/group_by.php @@ -0,0 +1,62 @@ + $i < 2 ? null : $i + 5 + * ) + * => Dict( + * 7 => [2], 8 => [3], 9 => [4], 10 => [5], 11 => [6], 12 => [7], 13 => [8], 14 => [9], 15 => [10] + * ) + * + * Dict\group_by( + * [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + * fn($i) => $i < 2 ? null : ($i >= 7 ? 12 : $i +5) + * ) + * => Dict(7 => [2], 8 => [3], 9 => [4], 10 => [5], 11 => [6], 12 => [7, 8, 9, 10]) + * + * @template Tk of array-key + * @template Tv + * + * @param iterable $values + * @param (callable(Tv): ?Tk) $key_func + * + * @return array> + */ +function group_by(iterable $values, callable $key_func): array +{ + $result = []; + foreach ($values as $value) { + $key = $key_func($value); + if (null === $key) { + continue; + } + + Psl\invariant( + Type\is_arraykey($key), + 'Expected $key_func to return a value of type array-key, value of type (%s) returned.', + gettype($key) + ); + + /** @var Tk $key */ + $result[$key] = $result[$key] ?? []; + $result[$key][] = $value; + } + + return $result; +} diff --git a/src/Psl/Dict/map.php b/src/Psl/Dict/map.php new file mode 100644 index 000000000..90818f473 --- /dev/null +++ b/src/Psl/Dict/map.php @@ -0,0 +1,37 @@ + $i * 2); + * => Dict(2, 4, 6, 8, 10) + * + * @psalm-template Tk of array-key + * @psalm-template Tv + * @psalm-template T + * + * @psalm-param iterable $iterable Iterable to be mapped over + * @psalm-param (callable(Tv): T) $function + * + * @psalm-return array + */ +function map(iterable $iterable, callable $function): array +{ + $result = []; + foreach ($iterable as $key => $value) { + $result[$key] = $function($value); + } + + return $result; +} diff --git a/src/Psl/Dict/map_keys.php b/src/Psl/Dict/map_keys.php new file mode 100644 index 000000000..bba337ab7 --- /dev/null +++ b/src/Psl/Dict/map_keys.php @@ -0,0 +1,37 @@ + 1, 1 => 2, 2 => 3, 3 => 4, 4 => 5], fn($i) => $i * 2); + * => Dict(0 => 1, 2 => 2, 4 => 3, 6 => 4, 8 => 5) + * + * @psalm-template Tk1 of array-key + * @psalm-template Tk2 of array-key + * @psalm-template Tv + * + * @psalm-param iterable $iterable Iterable to be mapped over + * @psalm-param (callable(Tk1): Tk2) $function + * + * @psalm-return array + */ +function map_keys(iterable $iterable, callable $function): array +{ + $result = []; + foreach ($iterable as $key => $value) { + $result[$function($key)] = $value; + } + + return $result; +} diff --git a/src/Psl/Dict/map_with_key.php b/src/Psl/Dict/map_with_key.php new file mode 100644 index 000000000..a9404312c --- /dev/null +++ b/src/Psl/Dict/map_with_key.php @@ -0,0 +1,37 @@ + $k + $v); + * => Dict(1, 3, 5, 7, 9) + * + * @psalm-template Tk of array-key + * @psalm-template Tv + * @psalm-template T + * + * @psalm-param iterable $iterable Iterable to be mapped over + * @psalm-param (callable(Tk,Tv): T) $function + * + * @psalm-return array + */ +function map_with_key(iterable $iterable, callable $function): array +{ + $result = []; + foreach ($iterable as $key => $value) { + $result[$key] = $function($key, $value); + } + + return $result; +} diff --git a/src/Psl/Dict/merge.php b/src/Psl/Dict/merge.php new file mode 100644 index 000000000..94c396435 --- /dev/null +++ b/src/Psl/Dict/merge.php @@ -0,0 +1,25 @@ + $first + * @param iterable ...$rest + * + * @return array + */ +function merge(iterable $first, iterable ...$rest): array +{ + /** @psalm-var list> $iterables */ + $iterables = [$first, ...$rest]; + + return flatten($iterables); +} diff --git a/src/Psl/Dict/partition.php b/src/Psl/Dict/partition.php new file mode 100644 index 000000000..fab4e7dc7 --- /dev/null +++ b/src/Psl/Dict/partition.php @@ -0,0 +1,32 @@ + $iterable + * @param (callable(Tv): bool) $predicate + * + * @return array{0: array, 1: array} + */ +function partition(iterable $iterable, callable $predicate): array +{ + $success = []; + $failure = []; + foreach ($iterable as $key => $value) { + if ($predicate($value)) { + $success[$key] = $value; + } else { + $failure[$key] = $value; + } + } + + return [$success, $failure]; +} diff --git a/src/Psl/Dict/partition_with_key.php b/src/Psl/Dict/partition_with_key.php new file mode 100644 index 000000000..869561b5f --- /dev/null +++ b/src/Psl/Dict/partition_with_key.php @@ -0,0 +1,32 @@ + $iterable + * @param (callable(Tk, Tv): bool) $predicate + * + * @return array{0: array, 1: array} + */ +function partition_with_key(iterable $iterable, callable $predicate): array +{ + $success = []; + $failure = []; + foreach ($iterable as $key => $value) { + if ($predicate($key, $value)) { + $success[$key] = $value; + } else { + $failure[$key] = $value; + } + } + + return [$success, $failure]; +} diff --git a/src/Psl/Dict/pull.php b/src/Psl/Dict/pull.php new file mode 100644 index 000000000..d8ea5f0b8 --- /dev/null +++ b/src/Psl/Dict/pull.php @@ -0,0 +1,44 @@ + Str\chr($i + 65), + * fn($i) => 2**$i, + * ) + * => Dict( + * 1 => 'A', 2 => 'B', 4 => 'C', 8 => 'D', 16 => 'E', 32 => 'F', + * 64 => 'G', 128 => 'H', 256 => 'I', 512 => 'J', 1024 => 'K' + * ) + * + * + * @psalm-template Tk1 + * @psalm-template Tv1 + * @psalm-template Tk2 of array-key + * @psalm-template Tv2 + * + * @psalm-param iterable $iterable + * @psalm-param (callable(Tv1): Tv2) $value_func + * @psalm-param (callable(Tv1): Tk2) $key_func + * + * @psalm-return array + */ +function pull(iterable $iterable, callable $value_func, callable $key_func): array +{ + $result = []; + foreach ($iterable as $value) { + $result[$key_func($value)] = $value_func($value); + } + + return $result; +} diff --git a/src/Psl/Dict/pull_with_key.php b/src/Psl/Dict/pull_with_key.php new file mode 100644 index 000000000..ab3817724 --- /dev/null +++ b/src/Psl/Dict/pull_with_key.php @@ -0,0 +1,43 @@ + Str\chr($v + $k + 65), + * fn($k, $v) => 2**($v+$k) + * ) + * => Dict( + * 1 => 'A', 4 => 'C', 16 => 'E', 64 => 'G', 256 => 'I', 1024 => 'K', + * 4096 => 'M', 16384 => 'O', 65536 => 'Q', 262144 => 'S', 1048576 => 'U' + * ) + * + * @template Tk1 + * @template Tv1 + * @template Tk2 of array-key + * @template Tv2 + * + * @param iterable $iterable + * @param (callable(Tk1, Tv1): Tv2) $value_func + * @param (callable(Tk1, Tv1): Tk2) $key_func + * + * @return array + */ +function pull_with_key(iterable $iterable, callable $value_func, callable $key_func): array +{ + $result = []; + foreach ($iterable as $key => $value) { + $result[$key_func($key, $value)] = $value_func($key, $value); + } + + return $result; +} diff --git a/src/Psl/Dict/reindex.php b/src/Psl/Dict/reindex.php new file mode 100644 index 000000000..47677ff74 --- /dev/null +++ b/src/Psl/Dict/reindex.php @@ -0,0 +1,45 @@ + 42, 'name' => 'foo'], + * ['id' => 24, 'name' => 'bar'] + * ]; + * + * Dict\reindex($users, fn($user) => $user['id']) + * => Dict( + * 42 => ['id' => 42, 'name' => 'foo'], + * 24 => ['id' => 24, 'name' => 'bar'] + * ) + * + * @psalm-template Tk1 + * @psalm-template Tk2 of array-key + * @psalm-template Tv + * + * @psalm-param iterable $iterable Iterable to reindex + * @psalm-param (callable(Tv): Tk2) $function + * + * @psalm-return array + */ +function reindex(iterable $iterable, callable $function): array +{ + $result = []; + foreach ($iterable as $value) { + $result[$function($value)] = $value; + } + + return $result; +} diff --git a/src/Psl/Dict/select_keys.php b/src/Psl/Dict/select_keys.php new file mode 100644 index 000000000..86bac837a --- /dev/null +++ b/src/Psl/Dict/select_keys.php @@ -0,0 +1,38 @@ + $iterable + * @param iterable $keys + * + * @return array + */ +function select_keys(iterable $iterable, iterable $keys): array +{ + $array = []; + foreach ($iterable as $k => $v) { + $array[$k] = $v; + } + + $result = []; + foreach ($keys as $key) { + if (Iter\contains_key($array, $key)) { + $result[$key] = $array[$key]; + } + } + + return $result; +} diff --git a/src/Psl/Dict/slice.php b/src/Psl/Dict/slice.php new file mode 100644 index 000000000..8ea66272e --- /dev/null +++ b/src/Psl/Dict/slice.php @@ -0,0 +1,54 @@ + Dict(0, 1, 2, 3, 4, 5) + * + * Dict\slice([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5], 5, 3) + * => Dict(0, 1, 2) + * + * @psalm-template Tk of array-key + * @psalm-template Tv + * + * @psalm-param iterable $iterable Iterable to take the slice from + * @psalm-param int $start Start offset + * @psalm-param int $length Length (if not specified all remaining values from the array are used) + * + * @psalm-return array + * + * @throws Psl\Exception\InvariantViolationException If the $start offset or $length are negative + */ +function slice(iterable $iterable, int $start, ?int $length = null): array +{ + Psl\invariant($start >= 0, 'Start offset must be non-negative.'); + Psl\invariant(null === $length || $length >= 0, 'Length must be non-negative.'); + + $result = []; + if (0 === $length) { + return $result; + } + + $i = 0; + foreach ($iterable as $key => $value) { + if ($i++ < $start) { + continue; + } + + $result[$key] = $value; + if (null !== $length && $i >= $start + $length) { + break; + } + } + + return $result; +} diff --git a/src/Psl/Dict/sort.php b/src/Psl/Dict/sort.php new file mode 100644 index 000000000..ae5cec0f7 --- /dev/null +++ b/src/Psl/Dict/sort.php @@ -0,0 +1,38 @@ + $iterable + * @param (callable(Tv, Tv): int)|null $comparator + * + * @return array + */ +function sort(iterable $iterable, ?callable $comparator = null): array +{ + $array = []; + foreach ($iterable as $k => $v) { + $array[$k] = $v; + } + + if (null !== $comparator) { + uasort($array, $comparator); + } else { + asort($array); + } + + return $array; +} diff --git a/src/Psl/Dict/sort_by.php b/src/Psl/Dict/sort_by.php new file mode 100644 index 000000000..9ccdd1f6e --- /dev/null +++ b/src/Psl/Dict/sort_by.php @@ -0,0 +1,60 @@ + $iterable + * @param (callable(Tv): Ts) $scalar_func + * @param (callable(Ts, Ts): int)|null $comparator + * + * @return array + */ +function sort_by(iterable $iterable, callable $scalar_func, ?callable $comparator = null): array +{ + $comparator ??= + /** + * @psalm-param Ts $a + * @psalm-param Ts $b + */ + static fn ($a, $b): int => $a <=> $b; + + $tuple_comparator = + /** + * @psalm-param array{0: Ts, 1: Tv} $a + * @psalm-param array{0: Ts, 1: Tv} $b + */ + static fn ($a, $b): int => $comparator($a[0], $b[0]); + + /** + * @psalm-var array $tuples + */ + $tuples = []; + foreach ($iterable as $k => $v) { + $tuples[$k] = [$scalar_func($v), $v]; + } + + /** + * @psalm-var array $sorted + */ + $sorted = namespace\sort($tuples, $tuple_comparator); + + /** @psalm-var array $result */ + $result = []; + foreach ($sorted as $k => $v) { + $result[$k] = $v[1]; + } + + return $result; +} diff --git a/src/Psl/Dict/sort_by_key.php b/src/Psl/Dict/sort_by_key.php new file mode 100644 index 000000000..7b0863d1c --- /dev/null +++ b/src/Psl/Dict/sort_by_key.php @@ -0,0 +1,38 @@ + $iterable + * @param (callable(Tk, Tk): int)|null $comparator + * + * @return array + */ +function sort_by_key(iterable $iterable, ?callable $comparator = null): array +{ + $result = []; + foreach ($iterable as $k => $v) { + $result[$k] = $v; + } + + if ($comparator) { + uksort($result, $comparator); + } else { + ksort($result); + } + + return $result; +} diff --git a/src/Psl/Dict/take.php b/src/Psl/Dict/take.php new file mode 100644 index 000000000..2a295c949 --- /dev/null +++ b/src/Psl/Dict/take.php @@ -0,0 +1,25 @@ + $iterable Iterable to take the elements from + * @psalm-param int $n Number of elements to take from the start + * + * @psalm-return array + * + * @throws Psl\Exception\InvariantViolationException If the $n is negative + */ +function take(iterable $iterable, int $n): array +{ + return slice($iterable, 0, $n); +} diff --git a/src/Psl/Dict/take_while.php b/src/Psl/Dict/take_while.php new file mode 100644 index 000000000..1e2a22bb7 --- /dev/null +++ b/src/Psl/Dict/take_while.php @@ -0,0 +1,39 @@ + $i > 0) + * => Dict(3, 1, 4) + * + * @psalm-template Tk of array-key + * @psalm-template Tv + * + * @psalm-param iterable $iterable Iterable to take values from + * @psalm-param (callable(Tv): bool) $predicate + * + * @psalm-return array + */ +function take_while(iterable $iterable, callable $predicate): array +{ + $result = []; + foreach ($iterable as $key => $value) { + if (!$predicate($value)) { + return $result; + } + + $result[$key] = $value; + } + + + return $result; +} diff --git a/src/Psl/Dict/unique.php b/src/Psl/Dict/unique.php new file mode 100644 index 000000000..358901ece --- /dev/null +++ b/src/Psl/Dict/unique.php @@ -0,0 +1,30 @@ + $iterable + * + * @psalm-return array + */ +function unique(iterable $iterable): array +{ + return unique_by( + $iterable, + /** + * @psalm-param Tv $v + * + * @psalm-return Tv + * + * @psalm-pure + */ + static fn($v) => $v + ); +} diff --git a/src/Psl/Dict/unique_by.php b/src/Psl/Dict/unique_by.php new file mode 100644 index 000000000..79f600888 --- /dev/null +++ b/src/Psl/Dict/unique_by.php @@ -0,0 +1,46 @@ + $iterable + * @psalm-param (callable(Tv): Ts) $scalar_func + * + * @psalm-return array + */ +function unique_by(iterable $iterable, callable $scalar_func): array +{ + /** @psalm-var array $unique */ + $unique = []; + /** @psalm-var array $original_values */ + $original_values = []; + foreach ($iterable as $k => $v) { + $original_values[$k] = $v; + /** @psalm-var Ts $scalar */ + $scalar = $scalar_func($v); + + if (!Iter\contains($unique, $scalar)) { + $unique[$k] = $scalar; + } + } + + /** @psalm-var array $result */ + $result = []; + foreach ($unique as $k => $_) { + $result[$k] = $original_values[$k]; + } + + return $result; +} diff --git a/src/Psl/Internal/Loader.php b/src/Psl/Internal/Loader.php index 701b8b1bd..ebdf7758c 100644 --- a/src/Psl/Internal/Loader.php +++ b/src/Psl/Internal/Loader.php @@ -96,6 +96,37 @@ final class Loader 'Psl\Arr\map', 'Psl\Arr\map_keys', 'Psl\Arr\map_with_key', + 'Psl\Dict\associate', + 'Psl\Dict\drop', + 'Psl\Dict\drop_while', + 'Psl\Dict\equal', + 'Psl\Dict\filter', + 'Psl\Dict\filter_keys', + 'Psl\Dict\filter_with_key', + 'Psl\Dict\flatten', + 'Psl\Dict\flip', + 'Psl\Dict\from_entries', + 'Psl\Dict\from_iterable', + 'Psl\Dict\from_keys', + 'Psl\Dict\group_by', + 'Psl\Dict\map', + 'Psl\Dict\map_keys', + 'Psl\Dict\map_with_key', + 'Psl\Dict\merge', + 'Psl\Dict\partition', + 'Psl\Dict\partition_with_key', + 'Psl\Dict\pull', + 'Psl\Dict\pull_with_key', + 'Psl\Dict\reindex', + 'Psl\Dict\select_keys', + 'Psl\Dict\slice', + 'Psl\Dict\sort', + 'Psl\Dict\sort_by', + 'Psl\Dict\sort_by_key', + 'Psl\Dict\take', + 'Psl\Dict\take_while', + 'Psl\Dict\unique', + 'Psl\Dict\unique_by', 'Psl\Fun\after', 'Psl\Fun\identity', 'Psl\Fun\pipe', diff --git a/src/Psl/Iter/drop.php b/src/Psl/Iter/drop.php index 51d8dff5f..2dc71628d 100644 --- a/src/Psl/Iter/drop.php +++ b/src/Psl/Iter/drop.php @@ -5,6 +5,7 @@ namespace Psl\Iter; use Psl; +use Psl\Dict; /** * Drops the first n items from an iterable. @@ -23,8 +24,13 @@ * @psalm-return Iterator * * @throws Psl\Exception\InvariantViolationException If the $n is negative + * + * @deprecated use `Dict\drop` instead. + * + * @see Dict\drop() */ function drop(iterable $iterable, int $n): Iterator { + /** @psalm-suppress DeprecatedFunction */ return slice($iterable, $n); } diff --git a/src/Psl/Iter/drop_while.php b/src/Psl/Iter/drop_while.php index 2eced453e..4285056ec 100644 --- a/src/Psl/Iter/drop_while.php +++ b/src/Psl/Iter/drop_while.php @@ -5,6 +5,7 @@ namespace Psl\Iter; use Generator; +use Psl\Dict; /** * Drops items from an iterable until the predicate fails for the first time. @@ -24,6 +25,8 @@ * @psalm-param (callable(Tv): bool) $predicate * * @psalm-return Iterator + * + * @deprecated use `Dict\drop_while` instead. */ function drop_while(iterable $iterable, callable $predicate): Iterator { diff --git a/src/Psl/Iter/filter.php b/src/Psl/Iter/filter.php index aead21873..cdc0511e9 100644 --- a/src/Psl/Iter/filter.php +++ b/src/Psl/Iter/filter.php @@ -6,6 +6,7 @@ use Closure; use Generator; +use Psl\Dict; /** * Returns a generator containing only the values for which the given predicate @@ -26,6 +27,10 @@ * @psalm-param (callable(Tv): bool)|null $predicate * * @psalm-return Iterator + * + * @deprecated use `Dict\filter` instead. + * + * @see Dict\filter() */ function filter(iterable $iterable, ?callable $predicate = null): Iterator { diff --git a/src/Psl/Iter/filter_keys.php b/src/Psl/Iter/filter_keys.php index b8214f9ef..85d89dc6d 100644 --- a/src/Psl/Iter/filter_keys.php +++ b/src/Psl/Iter/filter_keys.php @@ -6,6 +6,7 @@ use Closure; use Generator; +use Psl\Dict; /** * Returns an iterator containing only the keys for which the given predicate @@ -28,6 +29,10 @@ * @psalm-param (callable(Tk): bool)|null $predicate * * @psalm-return Iterator + * + * @deprecated use `Dict\filter_keys` instead. + * + * @see Dict\filter_keys() */ function filter_keys(iterable $iterable, ?callable $predicate = null): Iterator { diff --git a/src/Psl/Iter/filter_with_key.php b/src/Psl/Iter/filter_with_key.php index b791d41f8..79ca0bc21 100644 --- a/src/Psl/Iter/filter_with_key.php +++ b/src/Psl/Iter/filter_with_key.php @@ -6,6 +6,7 @@ use Generator; use Psl; +use Psl\Dict; /** * Returns an iterator containing only the keys and values for which the given predicate @@ -31,6 +32,10 @@ * @psalm-param (callable(Tk, Tv): bool)|null $predicate * * @psalm-return Iterator + * + * @deprecated use `Dict\filter_with_key` instead. + * + * @see Dict\filter_with_key() */ function filter_with_key(iterable $iterable, ?callable $predicate = null): Iterator { diff --git a/src/Psl/Iter/flatten.php b/src/Psl/Iter/flatten.php index 516886783..25568dba0 100644 --- a/src/Psl/Iter/flatten.php +++ b/src/Psl/Iter/flatten.php @@ -5,6 +5,7 @@ namespace Psl\Iter; use Generator; +use Psl\Dict; /** * Returns an iterator formed by merging the iterable elements of the @@ -16,6 +17,10 @@ * @psalm-param iterable> $iterables * * @psalm-return Iterator + * + * @deprecated use `Dict\flatten` instead. + * + * @see Dict\flatten() */ function flatten(iterable $iterables): Iterator { diff --git a/src/Psl/Iter/flip.php b/src/Psl/Iter/flip.php index e589479ba..9e01d1801 100644 --- a/src/Psl/Iter/flip.php +++ b/src/Psl/Iter/flip.php @@ -20,6 +20,10 @@ * @psalm-param iterable $iterable * * @psalm-return Iterator + * + * @deprecated use `Dict\flip` instead. + * + * @see Dict\flip() */ function flip(iterable $iterable): Iterator { diff --git a/src/Psl/Iter/from_entries.php b/src/Psl/Iter/from_entries.php index 8ef8937f7..bbbd1b4b7 100644 --- a/src/Psl/Iter/from_entries.php +++ b/src/Psl/Iter/from_entries.php @@ -5,6 +5,7 @@ namespace Psl\Iter; use Generator; +use Psl\Dict; /** * Returns an iterator where each mapping is defined by the given key/value @@ -16,6 +17,10 @@ * @psalm-param iterable $entries * * @psalm-return Iterator + * + * @deprecated use `Dict\from_entries` instead. + * + * @see Dict\from_entries() */ function from_entries(iterable $entries): Iterator { diff --git a/src/Psl/Iter/from_keys.php b/src/Psl/Iter/from_keys.php index bd979ff80..3fc8d3b63 100644 --- a/src/Psl/Iter/from_keys.php +++ b/src/Psl/Iter/from_keys.php @@ -5,6 +5,7 @@ namespace Psl\Iter; use Generator; +use Psl\Dict; /** * Returns an iterator where each value is the result of calling the given @@ -17,6 +18,10 @@ * @psalm-param (callable(Tk): Tv) $value_func * * @psalm-return Iterator + * + * @deprecated use `Dict\from_keys` instead. + * + * @see Dict\from_keys() */ function from_keys(iterable $keys, callable $value_func): Iterator { diff --git a/src/Psl/Iter/map.php b/src/Psl/Iter/map.php index 0a989709f..47556e25f 100644 --- a/src/Psl/Iter/map.php +++ b/src/Psl/Iter/map.php @@ -5,6 +5,7 @@ namespace Psl\Iter; use Generator; +use Psl\Dict; /** * Applies a mapping function to all values of an iterator. @@ -27,6 +28,10 @@ * @psalm-param (callable(Tv): T) $function * * @psalm-return Iterator + * + * @deprecated use `Dict\map` instead. + * + * @see Dict\map() */ function map(iterable $iterable, callable $function): Iterator { diff --git a/src/Psl/Iter/map_keys.php b/src/Psl/Iter/map_keys.php index 7a9f2e455..dd326a9c6 100644 --- a/src/Psl/Iter/map_keys.php +++ b/src/Psl/Iter/map_keys.php @@ -5,6 +5,7 @@ namespace Psl\Iter; use Generator; +use Psl\Dict; /** * Applies a mapping function to all keys of an iterator. @@ -27,6 +28,10 @@ * @psalm-param (callable(Tk1): Tk2) $function * * @psalm-return Iterator + * + * @deprecated use `Dict\map_keys` instead. + * + * @see Dict\map_keys() */ function map_keys(iterable $iterable, callable $function): Iterator { diff --git a/src/Psl/Iter/map_with_key.php b/src/Psl/Iter/map_with_key.php index c1bf1eefd..c6592e0a2 100644 --- a/src/Psl/Iter/map_with_key.php +++ b/src/Psl/Iter/map_with_key.php @@ -5,6 +5,7 @@ namespace Psl\Iter; use Generator; +use Psl\Dict; /** * Applies a mapping function to all values of an iterator. @@ -25,6 +26,10 @@ * @psalm-param (callable(Tk,Tv): T) $function * * @psalm-return Iterator + * + * @deprecated use `Dict\map_with_key` instead. + * + * @see Dict\map_with_key() */ function map_with_key(iterable $iterable, callable $function): Iterator { diff --git a/src/Psl/Iter/merge.php b/src/Psl/Iter/merge.php index 39744ed6b..07aa5ca2f 100644 --- a/src/Psl/Iter/merge.php +++ b/src/Psl/Iter/merge.php @@ -4,6 +4,8 @@ namespace Psl\Iter; +use Psl\Dict; + /** * Merges multiple iterables into a lazy iterator. * @@ -21,6 +23,10 @@ * @psalm-param iterable ...$rest * * @psalm-return Iterator + * + * @deprecated use `Dict\merge` instead. + * + * @see Dict\merge() */ function merge(iterable $first, iterable ...$rest): Iterator { @@ -29,5 +35,6 @@ function merge(iterable $first, iterable ...$rest): Iterator $iterables[] = $iterable; } + /** @psalm-suppress DeprecatedFunction */ return flatten($iterables); } diff --git a/src/Psl/Iter/product.php b/src/Psl/Iter/product.php index f0d217cfb..217f8b40f 100644 --- a/src/Psl/Iter/product.php +++ b/src/Psl/Iter/product.php @@ -6,6 +6,7 @@ use Generator; use Psl\Arr; +use Psl\Dict; use Psl\Vec; /** @@ -28,12 +29,14 @@ * @psalm-param iterable ...$iterables Iterables to combine * * @psalm-return Iterator, list> + * + * @deprecated ( no replacement is provided ) */ function product(iterable ...$iterables): Iterator { return Iterator::from(static function () use ($iterables): Generator { /** @psalm-var list> $iterators */ - $iterators = Vec\values(map( + $iterators = Vec\values(Dict\map( $iterables, static fn (iterable $iterable) => Iterator::create($iterable) )); diff --git a/src/Psl/Iter/pull.php b/src/Psl/Iter/pull.php index d1fe20ba1..24382bbf2 100644 --- a/src/Psl/Iter/pull.php +++ b/src/Psl/Iter/pull.php @@ -5,6 +5,7 @@ namespace Psl\Iter; use Generator; +use Psl\Dict; /** * Returns an iterator where: @@ -33,6 +34,10 @@ * @psalm-param (callable(T): Tk) $key_func * * @psalm-return Iterator + * + * @deprecated use `Dict\pull` instead. + * + * @see Dict\pull() */ function pull(iterable $iterable, callable $value_func, callable $key_func): Iterator { diff --git a/src/Psl/Iter/pull_with_key.php b/src/Psl/Iter/pull_with_key.php index 186638d60..7a7a2d93f 100644 --- a/src/Psl/Iter/pull_with_key.php +++ b/src/Psl/Iter/pull_with_key.php @@ -5,6 +5,7 @@ namespace Psl\Iter; use Generator; +use Psl\Dict; /** * Returns an iterator where: @@ -33,6 +34,10 @@ * @psalm-param (callable(Tk1, Tv1): Tk2) $key_func * * @psalm-return Iterator + * + * @deprecated use `Dict\pull_with_key` instead. + * + * @see Dict\pull_with_key() */ function pull_with_key(iterable $iterable, callable $value_func, callable $key_func): Iterator { diff --git a/src/Psl/Iter/reindex.php b/src/Psl/Iter/reindex.php index 2e84d8a2e..53ba160f4 100644 --- a/src/Psl/Iter/reindex.php +++ b/src/Psl/Iter/reindex.php @@ -5,6 +5,7 @@ namespace Psl\Iter; use Generator; +use Psl\Dict; /** * Re-indexes an iterable by applying a function to all its values and @@ -35,6 +36,10 @@ * @psalm-param (callable(Tv): Tk2) $function * * @psalm-return Iterator + * + * @deprecated use `Dict\reindex` instead. + * + * @see Dict\reindex() */ function reindex(iterable $iterable, callable $function): Iterator { diff --git a/src/Psl/Iter/slice.php b/src/Psl/Iter/slice.php index ddd61973f..7bdf4d66b 100644 --- a/src/Psl/Iter/slice.php +++ b/src/Psl/Iter/slice.php @@ -6,6 +6,7 @@ use Generator; use Psl; +use Psl\Dict; /** * Takes a slice from an iterable. @@ -28,6 +29,10 @@ * @psalm-return Iterator * * @throws Psl\Exception\InvariantViolationException If the $start offset or $length are negative + * + * @deprecated use `Dict\slice` instead. + * + * @see Dict\slice() */ function slice(iterable $iterable, int $start, ?int $length = null): Iterator { diff --git a/src/Psl/Iter/take.php b/src/Psl/Iter/take.php index 717de1e66..c3da7ba28 100644 --- a/src/Psl/Iter/take.php +++ b/src/Psl/Iter/take.php @@ -5,6 +5,7 @@ namespace Psl\Iter; use Psl; +use Psl\Dict; /** * Take the first n elements from an iterable. @@ -17,8 +18,13 @@ * @psalm-return Iterator * * @throws Psl\Exception\InvariantViolationException If the $n is negative + * + * @deprecated use `Dict\take` instead. + * + * @see Dict\take() */ function take(iterable $iterable, int $n): Iterator { + /** @psalm-suppress DeprecatedFunction */ return slice($iterable, 0, $n); } diff --git a/src/Psl/Iter/take_while.php b/src/Psl/Iter/take_while.php index a65b450cc..91b536d53 100644 --- a/src/Psl/Iter/take_while.php +++ b/src/Psl/Iter/take_while.php @@ -5,6 +5,7 @@ namespace Psl\Iter; use Generator; +use Psl\Dict; /** * Takes items from an iterable until the predicate fails for the first time. @@ -24,6 +25,10 @@ * @psalm-param (callable(Tv): bool) $predicate * * @psalm-return Iterator + * + * @deprecated use `Dict\take_while` instead. + * + * @see Dict\take_while() */ function take_while(iterable $iterable, callable $predicate): Iterator { diff --git a/src/Psl/Iter/to_array_with_keys.php b/src/Psl/Iter/to_array_with_keys.php index ade3bdc45..f80cee0c9 100644 --- a/src/Psl/Iter/to_array_with_keys.php +++ b/src/Psl/Iter/to_array_with_keys.php @@ -4,6 +4,8 @@ namespace Psl\Iter; +use Psl\Dict; + /** * Copy the iterable into an array with keys. * @@ -13,6 +15,10 @@ * @psalm-param iterable $iterable * * @psalm-return array + * + * @deprecated use `Dict\from_iterable` instead. + * + * @see Dict\from_iterable() */ function to_array_with_keys(iterable $iterable): array { diff --git a/src/Psl/Iter/zip.php b/src/Psl/Iter/zip.php index ea9cdd4ec..a8fcf6d88 100644 --- a/src/Psl/Iter/zip.php +++ b/src/Psl/Iter/zip.php @@ -5,6 +5,7 @@ namespace Psl\Iter; use Generator; +use Psl\Dict; use Psl\Vec; /** @@ -43,7 +44,7 @@ function zip(iterable ...$iterables): Iterator } /** @psalm-var list> $iterators */ - $iterators = Vec\values(map( + $iterators = Vec\values(Dict\map( $iterables, /** * @psalm-param iterable $iterable @@ -56,7 +57,7 @@ function zip(iterable ...$iterables): Iterator apply($iterators, static fn (Iterator $iterator) => $iterator->rewind()); while (all($iterators, static fn (Iterator $iterator) => $iterator->valid())) { /** @psalm-var list $keys */ - $keys = Vec\values(map( + $keys = Vec\values(Dict\map( $iterators, /** * @psalm-param Iterator $iterator @@ -67,7 +68,7 @@ function zip(iterable ...$iterables): Iterator )); /** @psalm-var list $values */ - $values = Vec\values(map( + $values = Vec\values(Dict\map( $iterators, /** * @psalm-param Iterator $iterator diff --git a/src/Psl/Type/Internal/IterableType.php b/src/Psl/Type/Internal/IterableType.php index ec6c31b0a..3bfc622e5 100644 --- a/src/Psl/Type/Internal/IterableType.php +++ b/src/Psl/Type/Internal/IterableType.php @@ -79,7 +79,15 @@ public function coerce($value): iterable } /** @var iterable */ - return Iter\from_entries($entries); + return Iter\Iterator::from((static function () use ($entries) { + /** + * @var Tk $key + * @var Tv $value + */ + foreach ($entries as [$key, $value]) { + yield $key => $value; + } + })); } throw CoercionException::withValue($value, $this->toString(), $this->getTrace()); @@ -124,7 +132,15 @@ public function assert($value): iterable } /** @var iterable */ - return Iter\from_entries($entries); + return Iter\Iterator::from((static function () use ($entries) { + /** + * @var Tk $key + * @var Tv $value + */ + foreach ($entries as [$key, $value]) { + yield $key => $value; + } + })); } throw AssertException::withValue($value, $this->toString(), $this->getTrace()); diff --git a/src/Psl/Type/Internal/MapType.php b/src/Psl/Type/Internal/MapType.php index acf5ad7fc..8a234259c 100644 --- a/src/Psl/Type/Internal/MapType.php +++ b/src/Psl/Type/Internal/MapType.php @@ -5,7 +5,7 @@ namespace Psl\Type\Internal; use Psl\Collection; -use Psl\Iter; +use Psl\Dict; use Psl\Str; use Psl\Type; use Psl\Type\Exception\AssertException; @@ -81,11 +81,11 @@ public function coerce($value): Collection\MapInterface ]; } - /** @psalm-var Iter\Iterator $iterator */ - $iterator = Iter\from_entries($entries); + /** @psalm-var array $dict */ + $dict = Dict\from_entries($entries); /** @var Collection\Map */ - return new Collection\Map($iterator); + return new Collection\Map($dict); } throw CoercionException::withValue($value, $this->toString(), $this->getTrace()); @@ -132,11 +132,11 @@ public function assert($value): Collection\MapInterface ]; } - /** @psalm-var Iter\Iterator $iterator */ - $iterator = Iter\from_entries($entries); + /** @psalm-var array $dict */ + $dict = Dict\from_entries($entries); /** @var Collection\Map */ - return new Collection\Map($iterator); + return new Collection\Map($dict); } throw AssertException::withValue($value, $this->toString(), $this->getTrace()); diff --git a/src/Psl/Type/Internal/MutableMapType.php b/src/Psl/Type/Internal/MutableMapType.php index a8c1da6e0..c70572339 100644 --- a/src/Psl/Type/Internal/MutableMapType.php +++ b/src/Psl/Type/Internal/MutableMapType.php @@ -5,7 +5,7 @@ namespace Psl\Type\Internal; use Psl\Collection; -use Psl\Iter; +use Psl\Dict; use Psl\Str; use Psl\Type; use Psl\Type\Exception\AssertException; @@ -82,11 +82,11 @@ public function coerce($value): Collection\MutableMapInterface ]; } - /** @psalm-var Iter\Iterator $iterator */ - $iterator = Iter\from_entries($entries); + /** @psalm-var array $dict */ + $dict = Dict\from_entries($entries); /** @var Collection\MutableMap */ - return new Collection\MutableMap($iterator); + return new Collection\MutableMap($dict); } throw CoercionException::withValue($value, $this->toString(), $this->getTrace()); @@ -133,11 +133,11 @@ public function assert($value): Collection\MutableMapInterface ]; } - /** @psalm-var Iter\Iterator $iterator */ - $iterator = Iter\from_entries($entries); + /** @psalm-var array $dict */ + $dict = Dict\from_entries($entries); /** @var Collection\MutableMap */ - return new Collection\MutableMap($iterator); + return new Collection\MutableMap($dict); } throw AssertException::withValue($value, $this->toString(), $this->getTrace()); diff --git a/tests/Psl/Dict/AssociateTest.php b/tests/Psl/Dict/AssociateTest.php new file mode 100644 index 000000000..1f8ca17c9 --- /dev/null +++ b/tests/Psl/Dict/AssociateTest.php @@ -0,0 +1,42 @@ + 1, 'b' => 2, 'c' => 3], Dict\associate( + ['a', 'b', 'c'], + [1, 2, 3] + )); + } + + public function testAssociateWithMissingKeys(): void + { + $this->expectException(Psl\Exception\InvariantViolationException::class); + $this->expectExceptionMessage('Expected length of $keys and $values to be the same'); + + Dict\associate( + ['a', 'b', 'c'], + [1, 2, 3, 4] + ); + } + + public function testAssociateWithMissingValues(): void + { + $this->expectException(Psl\Exception\InvariantViolationException::class); + $this->expectExceptionMessage('Expected length of $keys and $values to be the same'); + + Dict\associate( + ['a', 'b', 'c', 'd', 'e', 'f'], + [1, 2, 3, 4] + ); + } +} diff --git a/tests/Psl/Dict/DropTest.php b/tests/Psl/Dict/DropTest.php new file mode 100644 index 000000000..a47ec17fd --- /dev/null +++ b/tests/Psl/Dict/DropTest.php @@ -0,0 +1,29 @@ + 4, 4 => 5], [1, 2, 3, 4, 5], 3]; + yield [[2 => 3, 3 => 4, 4 => 5], [1, 2, 3, 4, 5], 2]; + yield [[], [1, 2, 3, 4, 5], 5]; + } +} diff --git a/tests/Psl/Dict/DropWhileTest.php b/tests/Psl/Dict/DropWhileTest.php new file mode 100644 index 000000000..cb4b6820f --- /dev/null +++ b/tests/Psl/Dict/DropWhileTest.php @@ -0,0 +1,29 @@ + false]; + yield [[3 => 4, 4 => 5], [1, 2, 3, 4, 5], static fn (int $i) => $i <= 3]; + yield [[2 => 3, 3 => 4, 4 => 5], [1, 2, 3, 4, 5], static fn (int $i) => $i <= 2]; + yield [[], [1, 2, 3, 4, 5], static fn (int $_) => true]; + } +} diff --git a/tests/Psl/Dict/FilterTest.php b/tests/Psl/Dict/FilterTest.php new file mode 100644 index 000000000..2acd126ae --- /dev/null +++ b/tests/Psl/Dict/FilterTest.php @@ -0,0 +1,30 @@ + false]; + yield [['a', 'b'], ['a', 'b'], static fn (string $_): bool => true]; + yield [['a'], ['a', 'b'], static fn (string $v): bool => 'b' !== $v]; + } +} diff --git a/tests/Psl/Dict/FilterWithKeyTest.php b/tests/Psl/Dict/FilterWithKeyTest.php new file mode 100644 index 000000000..1132f1f83 --- /dev/null +++ b/tests/Psl/Dict/FilterWithKeyTest.php @@ -0,0 +1,34 @@ + false]; + yield [['a', 'b'], ['a', 'b'], static fn (int $_k, string $_v): bool => true]; + yield [['a'], ['a', 'b'], static fn (int $k, string $v): bool => 'b' !== $v]; + yield [[], ['a', 'b'], static fn (int $k, string $v): bool => 'b' !== $v && 0 !== $k]; + yield [['a'], ['a', 'b'], static fn (int $k, string $v): bool => 'b' !== $v && 1 !== $k]; + yield [[], ['a', 'b'], static fn (int $k, string $v): bool => 'a' !== $v && 1 !== $k]; + yield [[1 => 'b'], ['a', 'b'], static fn (int $k, string $v): bool => 'a' !== $v && 0 !== $k]; + } +} diff --git a/tests/Psl/Dict/FromEntriesTest.php b/tests/Psl/Dict/FromEntriesTest.php new file mode 100644 index 000000000..46269c80d --- /dev/null +++ b/tests/Psl/Dict/FromEntriesTest.php @@ -0,0 +1,29 @@ + false); + + static::assertSame('hello', Iter\first_key($actual)); + static::assertSame('world', Iter\last_key($actual)); + static::assertFalse(Iter\first($actual)); + static::assertFalse(Iter\last($actual)); + } +} diff --git a/tests/Psl/Dict/MapKeysTest.php b/tests/Psl/Dict/MapKeysTest.php new file mode 100644 index 000000000..8d4ca3aea --- /dev/null +++ b/tests/Psl/Dict/MapKeysTest.php @@ -0,0 +1,29 @@ + $k]; + yield [[1, 2 => 2, 4 => 3], [1, 2, 3], static fn (int $k): int => $k * 2]; + yield [['0' => 1, '1' => 2, '2' => 3], [1, 2, 3], static fn (int $k): string => (string) $k]; + yield [[], [], static fn (int $k): string => (string) $k]; + } +} diff --git a/tests/Psl/Dict/MapTest.php b/tests/Psl/Dict/MapTest.php new file mode 100644 index 000000000..27e375f6f --- /dev/null +++ b/tests/Psl/Dict/MapTest.php @@ -0,0 +1,29 @@ + $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]; + } +} diff --git a/tests/Psl/Dict/MapWithKeyTest.php b/tests/Psl/Dict/MapWithKeyTest.php new file mode 100644 index 000000000..ea97bea56 --- /dev/null +++ b/tests/Psl/Dict/MapWithKeyTest.php @@ -0,0 +1,29 @@ + $k + $v]; + yield [[0, 4, 16], [1, 2, 3], static fn (int $k, int $v): int => $k * (2 ** $v)]; + yield [['1', '3', '5'], [1, 2, 3], static fn (int $k, int $v): string => (string) ($k + $v)]; + yield [[], [], static fn (int $k, int $v): string => (string) ($k + $v)]; + } +} diff --git a/tests/Psl/Dict/MergeTest.php b/tests/Psl/Dict/MergeTest.php new file mode 100644 index 000000000..3b1379dfe --- /dev/null +++ b/tests/Psl/Dict/MergeTest.php @@ -0,0 +1,40 @@ + 'b', 'b' => 'c', 'c' => 'd', 'd' => 'e'], + + ['a' => 'foo', 'b' => 'bar'], + ['a' => 'b'], + ['b' => 'c', 'c' => 'd'], + ['d' => 'baz'], + ['d' => 'e'], + ], + + [ + [1, 2, 9, 8], + [0 => 1, 1 => 2], + [2 => 9, 3 => 8], + ], + ]; + } +} diff --git a/tests/Psl/Dict/PartitionTest.php b/tests/Psl/Dict/PartitionTest.php new file mode 100644 index 000000000..3714e05c0 --- /dev/null +++ b/tests/Psl/Dict/PartitionTest.php @@ -0,0 +1,55 @@ + 'bar', 2 => 'baz'], [0 => 'foo', 3 => 'qux']], + ['foo', 'bar', 'baz', 'qux'], + static fn (string $str) => Str\starts_with($str, 'b'), + ], + + [ + [[0 => 'foo', 3 => 'qux'], [1 => 'bar', 2 => 'baz']], + ['foo', 'bar', 'baz', 'qux'], + static fn (string $str) => !Str\starts_with($str, 'b'), + ], + + [ + [[], []], + [], + static fn ($_) => false, + ], + + [ + [[], ['foo', 'bar', 'baz', 'qux']], + ['foo', 'bar', 'baz', 'qux'], + static fn (string $str) => false, + ], + + [ + [['foo', 'bar', 'baz', 'qux'], []], + ['foo', 'bar', 'baz', 'qux'], + static fn (string $str) => true, + ], + ]; + } +} diff --git a/tests/Psl/Dict/PartitionWithKeyTest.php b/tests/Psl/Dict/PartitionWithKeyTest.php new file mode 100644 index 000000000..113e5e29c --- /dev/null +++ b/tests/Psl/Dict/PartitionWithKeyTest.php @@ -0,0 +1,67 @@ + 'bar', 2 => 'baz'], [0 => 'foo', 3 => 'qux']], + ['foo', 'bar', 'baz', 'qux'], + static fn (int $k, string $str) => Str\starts_with($str, 'b'), + ], + + [ + [[0 => 'foo', 3 => 'qux'], [1 => 'bar', 2 => 'baz']], + ['foo', 'bar', 'baz', 'qux'], + static fn (int $k, string $str) => !Str\starts_with($str, 'b'), + ], + + [ + [[], []], + [], + static fn ($_k, $_v) => false, + ], + + [ + [[], ['foo', 'bar', 'baz', 'qux']], + ['foo', 'bar', 'baz', 'qux'], + static fn (int $k, string $str) => false, + ], + + [ + [['foo', 'bar', 'baz', 'qux'], []], + ['foo', 'bar', 'baz', 'qux'], + static fn (int $k, string $str) => true, + ], + + [ + [[1 => 'bar', 2 => 'baz', 3 => 'qux'], ['foo']], + ['foo', 'bar', 'baz', 'qux'], + static fn (int $k, string $str) => (bool) $k, + ], + + [ + [['foo'], [1 => 'bar', 2 => 'baz', 3 => 'qux']], + ['foo', 'bar', 'baz', 'qux'], + static fn (int $k, string $str) => !((bool) $k), + ], + ]; + } +} diff --git a/tests/Psl/Dict/PullTest.php b/tests/Psl/Dict/PullTest.php new file mode 100644 index 000000000..243340d9e --- /dev/null +++ b/tests/Psl/Dict/PullTest.php @@ -0,0 +1,27 @@ + Str\chr($i + 65), + static fn ($i) => 2 ** $i + ); + + static::assertSame([ + 1 => 'A', 2 => 'B', 4 => 'C', 8 => 'D', 16 => 'E', 32 => 'F', + 64 => 'G', 128 => 'H', 256 => 'I', 512 => 'J', 1024 => 'K' + ], $result); + } +} diff --git a/tests/Psl/Dict/PullWithKeyTest.php b/tests/Psl/Dict/PullWithKeyTest.php new file mode 100644 index 000000000..458bd13f7 --- /dev/null +++ b/tests/Psl/Dict/PullWithKeyTest.php @@ -0,0 +1,27 @@ + Str\chr($v + $k + 65), + static fn ($k, $v) => 2 ** ($v + $k) + ); + + static::assertSame([ + 1 => 'A', 4 => 'C', 16 => 'E', 64 => 'G', 256 => 'I', 1024 => 'K', + 4096 => 'M', 16384 => 'O', 65536 => 'Q', 262144 => 'S', 1048576 => 'U' + ], $result); + } +} diff --git a/tests/Psl/Dict/ReindexTest.php b/tests/Psl/Dict/ReindexTest.php new file mode 100644 index 000000000..140077132 --- /dev/null +++ b/tests/Psl/Dict/ReindexTest.php @@ -0,0 +1,18 @@ + $value); + + static::assertSame([1 => 1, 2 => 2, 3 => 3], $result); + } +} diff --git a/tests/Psl/Dict/TakeTest.php b/tests/Psl/Dict/TakeTest.php new file mode 100644 index 000000000..b31ecb309 --- /dev/null +++ b/tests/Psl/Dict/TakeTest.php @@ -0,0 +1,27 @@ +expectException(Psl\Exception\InvariantViolationException::class); + $this->expectExceptionMessage('Length must be non-negative.'); + + Dict\take([1, 2, 3], -3); + } +} diff --git a/tests/Psl/Dict/TakeWhileTest.php b/tests/Psl/Dict/TakeWhileTest.php new file mode 100644 index 000000000..5dc702b7d --- /dev/null +++ b/tests/Psl/Dict/TakeWhileTest.php @@ -0,0 +1,29 @@ + false]; + yield [[1, 2, 3], [1, 2, 3, 4, 5], static fn (int $i) => $i <= 3]; + yield [[1, 2], [1, 2, 3, 4, 5], static fn (int $i) => $i <= 2]; + yield [[1, 2, 3, 4, 5], [1, 2, 3, 4, 5], static fn (int $_) => true]; + } +} diff --git a/tests/Psl/Dict/UniqueByTest.php b/tests/Psl/Dict/UniqueByTest.php new file mode 100644 index 000000000..e5ec4e0c5 --- /dev/null +++ b/tests/Psl/Dict/UniqueByTest.php @@ -0,0 +1,37 @@ + 'a', 4 => 'saif'], + ['a', 'b', 'c', 'd', 'saif', 'jack'], + static fn (string $value): int => Str\length($value), + ], + + [ + [0 => 'foo', 2 => 'bar', 4 => '@baz'], + ['foo', '@foo', 'bar', '@bar', '@baz'], + static fn (string $value): string => Str\replace($value, '@', ''), + ], + ]; + } +} diff --git a/tests/Psl/Dict/UniqueTest.php b/tests/Psl/Dict/UniqueTest.php new file mode 100644 index 000000000..96935c2d7 --- /dev/null +++ b/tests/Psl/Dict/UniqueTest.php @@ -0,0 +1,39 @@ +> @@ -21,21 +23,21 @@ public function getType(): Type\Type public function getValidCoercions(): iterable { yield [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]; - yield [Iter\range(1, 10), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]; - yield [Iter\range(1, 10), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]; + yield [Vec\range(1, 10), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]; + yield [Vec\range(1, 10), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]; yield [ - Iter\map(Iter\range(1, 10), static fn (int $value): string => (string) $value), + Dict\map(Vec\range(1, 10), static fn (int $value): string => (string) $value), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] ]; yield [ - Iter\map_keys(Iter\range(1, 10), static fn (int $key): string => (string) $key), + Dict\map_keys(Vec\range(1, 10), static fn (int $key): string => (string) $key), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] ]; yield [ - Iter\map(Iter\range(1, 10), static fn (int $value): string => Str\format('00%d', $value)), + Dict\map(Vec\range(1, 10), static fn (int $value): string => Str\format('00%d', $value)), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] ]; } @@ -68,8 +70,8 @@ public function getToStringExamples(): iterable */ protected function equals($a, $b): bool { - $a = Iter\to_array_with_keys($a); - $b = Iter\to_array_with_keys($b); + $a = Dict\from_iterable($a); + $b = Dict\from_iterable($b); return $a === $b; } diff --git a/tests/Psl/Type/MapTypeTest.php b/tests/Psl/Type/MapTypeTest.php index cecf4ba5c..932257aa2 100644 --- a/tests/Psl/Type/MapTypeTest.php +++ b/tests/Psl/Type/MapTypeTest.php @@ -5,9 +5,11 @@ namespace Psl\Tests\Type; use Psl\Collection; +use Psl\Dict; use Psl\Iter; use Psl\Str; use Psl\Type; +use Psl\Vec; /** * @extends TypeTest> @@ -27,27 +29,27 @@ public function getValidCoercions(): iterable ]; yield [ - Iter\range(1, 10), + Vec\range(1, 10), new Collection\Map([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) ]; yield [ - Iter\range(1, 10), + Vec\range(1, 10), new Collection\Map([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) ]; yield [ - Iter\map(Iter\range(1, 10), static fn(int $value): string => (string)$value), + Dict\map(Vec\range(1, 10), static fn(int $value): string => (string)$value), new Collection\Map([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) ]; yield [ - Iter\map_keys(Iter\range(1, 10), static fn(int $key): string => (string)$key), + Dict\map_keys(Vec\range(1, 10), static fn(int $key): string => (string)$key), new Collection\Map([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) ]; yield [ - Iter\map(Iter\range(1, 10), static fn(int $value): string => Str\format('00%d', $value)), + Dict\map(Vec\range(1, 10), static fn(int $value): string => Str\format('00%d', $value)), new Collection\Map([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) ]; } diff --git a/tests/Psl/Type/MutableMapTypeTest.php b/tests/Psl/Type/MutableMapTypeTest.php index dcf7ef13d..49637f4ef 100644 --- a/tests/Psl/Type/MutableMapTypeTest.php +++ b/tests/Psl/Type/MutableMapTypeTest.php @@ -5,9 +5,11 @@ namespace Psl\Tests\Type; use Psl\Collection; +use Psl\Dict; use Psl\Iter; use Psl\Str; use Psl\Type; +use Psl\Vec; /** * @extends TypeTest> @@ -27,27 +29,27 @@ public function getValidCoercions(): iterable ]; yield [ - Iter\range(1, 10), + Vec\range(1, 10), new Collection\MutableMap([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) ]; yield [ - Iter\range(1, 10), + Vec\range(1, 10), new Collection\MutableMap([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) ]; yield [ - Iter\map(Iter\range(1, 10), static fn(int $value): string => (string)$value), + Dict\map(Vec\range(1, 10), static fn(int $value): string => (string)$value), new Collection\MutableMap([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) ]; yield [ - Iter\map_keys(Iter\range(1, 10), static fn(int $key): string => (string)$key), + Dict\map_keys(Vec\range(1, 10), static fn(int $key): string => (string)$key), new Collection\MutableMap([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) ]; yield [ - Iter\map(Iter\range(1, 10), static fn(int $value): string => Str\format('00%d', $value)), + Dict\map(Vec\range(1, 10), static fn(int $value): string => Str\format('00%d', $value)), new Collection\MutableMap([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) ]; diff --git a/tests/Psl/Type/MutableVectorTypeTest.php b/tests/Psl/Type/MutableVectorTypeTest.php index 335a13987..bd7e65b4b 100644 --- a/tests/Psl/Type/MutableVectorTypeTest.php +++ b/tests/Psl/Type/MutableVectorTypeTest.php @@ -5,9 +5,11 @@ namespace Psl\Tests\Type; use Psl\Collection; +use Psl\Dict; use Psl\Iter; use Psl\Str; use Psl\Type; +use Psl\Vec; /** * @extends TypeTest> @@ -32,27 +34,27 @@ public function getValidCoercions(): iterable ]; yield [ - Iter\range(1, 10), + Vec\range(1, 10), new Collection\MutableVector([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) ]; yield [ - Iter\range(1, 10), + Vec\range(1, 10), new Collection\MutableVector([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) ]; yield [ - Iter\map(Iter\range(1, 10), static fn(int $value): string => (string)$value), + Dict\map(Vec\range(1, 10), static fn(int $value): string => (string)$value), new Collection\MutableVector([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) ]; yield [ - Iter\map_keys(Iter\range(1, 10), static fn(int $key): string => (string)$key), + Dict\map_keys(Vec\range(1, 10), static fn(int $key): string => (string)$key), new Collection\MutableVector([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) ]; yield [ - Iter\map(Iter\range(1, 10), static fn(int $value): string => Str\format('00%d', $value)), + Dict\map(Vec\range(1, 10), static fn(int $value): string => Str\format('00%d', $value)), new Collection\MutableVector([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) ]; diff --git a/tests/Psl/Type/TypeTest.php b/tests/Psl/Type/TypeTest.php index 305d7b1f1..4309a8c9a 100644 --- a/tests/Psl/Type/TypeTest.php +++ b/tests/Psl/Type/TypeTest.php @@ -5,10 +5,11 @@ namespace Psl\Tests\Type; use PHPUnit\Framework\TestCase; -use Psl\Iter; +use Psl\Dict; use Psl\Type\Exception\AssertException; use Psl\Type\Exception\CoercionException; use Psl\Type\Type; +use Psl\Vec; /** * @template T @@ -41,7 +42,7 @@ abstract public function getToStringExamples(): iterable; public function getValidValues(): array { $non_unique = $this->getValidCoercions(); - $non_unique = Iter\map($non_unique, static fn ($tuple) => $tuple[1]); + $non_unique = Dict\map($non_unique, static fn ($tuple) => $tuple[1]); $out = []; foreach ($non_unique as $v) { @@ -63,7 +64,7 @@ public function getValidValues(): array public function getInvalidValues(): array { $rows = $this->getInvalidCoercions(); - $rows = Iter\to_array($rows); + $rows = Vec\values($rows); foreach ($this->getValidCoercions() as $arr) { [$value, $v] = $arr; if ($this->equals($v, $value)) { diff --git a/tests/Psl/Type/VectorTypeTest.php b/tests/Psl/Type/VectorTypeTest.php index 905b2bb5f..773e09f19 100644 --- a/tests/Psl/Type/VectorTypeTest.php +++ b/tests/Psl/Type/VectorTypeTest.php @@ -5,9 +5,11 @@ namespace Psl\Tests\Type; use Psl\Collection; +use Psl\Dict; use Psl\Iter; use Psl\Str; use Psl\Type; +use Psl\Vec; /** * @extends TypeTest> @@ -32,27 +34,27 @@ public function getValidCoercions(): iterable ]; yield [ - Iter\range(1, 10), + Vec\range(1, 10), new Collection\Vector([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) ]; yield [ - Iter\range(1, 10), + Vec\range(1, 10), new Collection\Vector([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) ]; yield [ - Iter\map(Iter\range(1, 10), static fn(int $value): string => (string)$value), + Dict\map(Vec\range(1, 10), static fn(int $value): string => (string)$value), new Collection\Vector([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) ]; yield [ - Iter\map_keys(Iter\range(1, 10), static fn(int $key): string => (string)$key), + Dict\map_keys(Vec\range(1, 10), static fn(int $key): string => (string)$key), new Collection\Vector([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) ]; yield [ - Iter\map(Iter\range(1, 10), static fn(int $value): string => Str\format('00%d', $value)), + Dict\map(Vec\range(1, 10), static fn(int $value): string => Str\format('00%d', $value)), new Collection\Vector([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) ];