move query helpers to internal namespace
This commit is contained in:
parent
483375240b
commit
b836bc5e8f
@ -26,6 +26,7 @@
|
||||
"./src/Predicates/index.php",
|
||||
"./src/Collections/Internal/functions.php",
|
||||
"./src/Collections/Internal/containers.php",
|
||||
"./src/Collections/Internal/queries.php",
|
||||
"./src/Collections/transforms.php",
|
||||
"./src/Collections/collectors.php",
|
||||
"./src/Collections/queries.php"
|
||||
|
||||
97
src/Collections/Internal/queries.php
Normal file
97
src/Collections/Internal/queries.php
Normal file
@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2026 Kacper Donat
|
||||
*
|
||||
* @author Kacper "Kadet" Donat <kacper@kadet.net>
|
||||
*
|
||||
* Full license available in separate LICENSE file
|
||||
*/
|
||||
|
||||
namespace Kadet\Functional\Collections\Internal;
|
||||
|
||||
use Kadet\Functional\Exception\EmptyCollectionException;
|
||||
|
||||
/**
|
||||
* Yields [key, value] pairs of $data from the end, without copying it where the container allows.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param iterable<mixed, mixed> $data
|
||||
*
|
||||
* @return \Generator<int, array{mixed, mixed}>
|
||||
*/
|
||||
function reversedEntries(iterable $data): \Generator
|
||||
{
|
||||
if (is_array($data)) {
|
||||
for (end($data); ($key = key($data)) !== null; prev($data)) {
|
||||
yield [$key, current($data)];
|
||||
}
|
||||
} elseif ($data instanceof \Ds\Seq || $data instanceof \Ds\Set) {
|
||||
for ($index = \count($data) - 1; $index >= 0; $index--) {
|
||||
yield [$index, $data->get($index)];
|
||||
}
|
||||
} elseif ($data instanceof \Ds\Map) {
|
||||
foreach ($data->pairs()->reversed() as $pair) {
|
||||
yield [$pair->key, $pair->value];
|
||||
}
|
||||
} else {
|
||||
$entries = [];
|
||||
foreach ($data as $key => $value) {
|
||||
$entries[] = [$key, $value];
|
||||
}
|
||||
|
||||
yield from array_reverse($entries);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shared implementation of {@see first()} and {@see find()}, so that the exception names the called function.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @return \Closure(iterable<mixed, mixed>): mixed
|
||||
*/
|
||||
function firstOf(string $name, ?callable $predicate, bool $required): \Closure
|
||||
{
|
||||
$predicate = $predicate === null ? null : callback($predicate);
|
||||
|
||||
return static function (iterable $data) use ($name, $predicate, $required) {
|
||||
foreach ($data as $key => $value) {
|
||||
if ($predicate === null || $predicate($value, $key)) {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
if ($required) {
|
||||
throw EmptyCollectionException::noMatch($name, $predicate !== null);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Shared implementation of {@see min()} (`$direction` -1) and {@see max()} (1).
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @return \Closure(iterable<mixed, mixed>): mixed
|
||||
*/
|
||||
function extremum(int $direction, ?callable $selector): \Closure
|
||||
{
|
||||
$selector = $selector === null ? static fn ($value) => $value : callback($selector);
|
||||
|
||||
return static function (iterable $data) use ($direction, $selector) {
|
||||
$best = null;
|
||||
$first = true;
|
||||
foreach ($data as $key => $value) {
|
||||
$value = $selector($value, $key);
|
||||
if ($first || ($value <=> $best) === $direction) {
|
||||
$best = $value;
|
||||
$first = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $best;
|
||||
};
|
||||
}
|
||||
@ -22,41 +22,11 @@ namespace Kadet\Functional\Collections;
|
||||
use Kadet\Functional\Exception\EmptyCollectionException;
|
||||
|
||||
use function Kadet\Functional\Collections\Internal\callback;
|
||||
use function Kadet\Functional\Collections\Internal\extremum;
|
||||
use function Kadet\Functional\Collections\Internal\firstOf;
|
||||
use function Kadet\Functional\Collections\Internal\reversedEntries;
|
||||
use function Kadet\Functional\compile;
|
||||
|
||||
/**
|
||||
* Yields [key, value] pairs of $data from the end, without copying it where the container allows.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param iterable<mixed, mixed> $data
|
||||
*
|
||||
* @return \Generator<int, array{mixed, mixed}>
|
||||
*/
|
||||
function reversedEntries(iterable $data): \Generator
|
||||
{
|
||||
if (is_array($data)) {
|
||||
for (end($data); ($key = key($data)) !== null; prev($data)) {
|
||||
yield [$key, current($data)];
|
||||
}
|
||||
} elseif ($data instanceof \Ds\Seq || $data instanceof \Ds\Set) {
|
||||
for ($index = \count($data) - 1; $index >= 0; $index--) {
|
||||
yield [$index, $data->get($index)];
|
||||
}
|
||||
} elseif ($data instanceof \Ds\Map) {
|
||||
foreach ($data->pairs()->reversed() as $pair) {
|
||||
yield [$pair->key, $pair->value];
|
||||
}
|
||||
} else {
|
||||
$entries = [];
|
||||
foreach ($data as $key => $value) {
|
||||
$entries[] = [$key, $value];
|
||||
}
|
||||
|
||||
yield from array_reverse($entries);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first value for which `$predicate($value, $key)` is truthy, or the first value without a predicate.
|
||||
*
|
||||
@ -145,32 +115,6 @@ function find(callable $predicate, bool $required = false): \Closure
|
||||
return firstOf('find', $predicate, $required);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shared implementation of {@see first()} and {@see find()}, so that the exception names the called function.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @return \Closure(iterable<mixed, mixed>): mixed
|
||||
*/
|
||||
function firstOf(string $name, ?callable $predicate, bool $required): \Closure
|
||||
{
|
||||
$predicate = $predicate === null ? null : callback($predicate);
|
||||
|
||||
return static function (iterable $data) use ($name, $predicate, $required) {
|
||||
foreach ($data as $key => $value) {
|
||||
if ($predicate === null || $predicate($value, $key)) {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
if ($required) {
|
||||
throw EmptyCollectionException::noMatch($name, $predicate !== null);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the collection holds `$value`, compared strictly (`Ds\Key::equals` when `$value` implements `Ds\Key`).
|
||||
*
|
||||
@ -330,32 +274,6 @@ function max(?callable $selector = null): \Closure
|
||||
return extremum(1, $selector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shared implementation of {@see min()} (`$direction` -1) and {@see max()} (1).
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @return \Closure(iterable<mixed, mixed>): mixed
|
||||
*/
|
||||
function extremum(int $direction, ?callable $selector): \Closure
|
||||
{
|
||||
$selector = $selector === null ? static fn ($value) => $value : callback($selector);
|
||||
|
||||
return static function (iterable $data) use ($direction, $selector) {
|
||||
$best = null;
|
||||
$first = true;
|
||||
foreach ($data as $key => $value) {
|
||||
$value = $selector($value, $key);
|
||||
if ($first || ($value <=> $best) === $direction) {
|
||||
$best = $value;
|
||||
$first = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $best;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Folds the collection into a single value with `$fn($carry, $value, $key)`, starting from `$initial`.
|
||||
*
|
||||
|
||||
Loading…
Reference in New Issue
Block a user