diff options
Diffstat (limited to 'vendor/ipl/stdlib/src/functions.php')
-rw-r--r-- | vendor/ipl/stdlib/src/functions.php | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/vendor/ipl/stdlib/src/functions.php b/vendor/ipl/stdlib/src/functions.php new file mode 100644 index 0000000..e7f9be0 --- /dev/null +++ b/vendor/ipl/stdlib/src/functions.php @@ -0,0 +1,128 @@ +<?php + +namespace ipl\Stdlib; + +use Generator; +use InvalidArgumentException; +use IteratorIterator; +use Traversable; +use stdClass; + +/** + * Detect and return the PHP type of the given subject + * + * If subject is an object, the name of the object's class is returned, otherwise the subject's type. + * + * @param mixed $subject + * + * @return string + */ +function get_php_type($subject) +{ + if (is_object($subject)) { + return get_class($subject); + } else { + return gettype($subject); + } +} + +/** + * Get the array value of the given subject + * + * @param array<mixed>|object|Traversable $subject + * + * @return array<mixed> + * + * @throws InvalidArgumentException If subject type is invalid + */ +function arrayval($subject) +{ + if (is_array($subject)) { + return $subject; + } + + if ($subject instanceof stdClass) { + return (array) $subject; + } + + if ($subject instanceof Traversable) { + // Works for generators too + return iterator_to_array($subject); + } + + throw new InvalidArgumentException(sprintf( + 'arrayval expects arrays, objects or instances of Traversable. Got %s instead.', + get_php_type($subject) + )); +} + +/** + * Get the first key of an iterable + * + * @param iterable<mixed> $iterable + * + * @return mixed The first key of the iterable if it is not empty, null otherwise + */ +function iterable_key_first($iterable) +{ + foreach ($iterable as $key => $_) { + return $key; + } + + return null; +} + +/** + * Get the first value of an iterable + * + * @param iterable<mixed> $iterable + * + * @return ?mixed + */ +function iterable_value_first($iterable) +{ + foreach ($iterable as $_ => $value) { + return $value; + } + + return null; +} + +/** + * Yield sets of items from a sorted traversable grouped by a specific criterion gathered from a callback + * + * The traversable must be sorted by the criterion. The callback must return at least the criterion, + * but can also return value and key in addition. + * + * @param Traversable<mixed, mixed> $traversable + * @param callable(mixed $value, mixed $key): array{0: mixed, 1?: mixed, 2?: mixed} $groupBy + * + * @return Generator + */ +function yield_groups(Traversable $traversable, callable $groupBy): Generator +{ + $iterator = new IteratorIterator($traversable); + $iterator->rewind(); + + if (! $iterator->valid()) { + return; + } + + list($criterion, $v, $k) = array_pad((array) $groupBy($iterator->current(), $iterator->key()), 3, null); + $group = [$k ?? $iterator->key() => $v ?? $iterator->current()]; + + $iterator->next(); + for (; $iterator->valid(); $iterator->next()) { + list($c, $v, $k) = array_pad((array) $groupBy($iterator->current(), $iterator->key()), 3, null); + if ($c !== $criterion) { + yield $criterion => $group; + + $group = []; + $criterion = $c; + } + + $group[$k ?? $iterator->key()] = $v ?? $iterator->current(); + } + + yield $criterion => $group; +} |