pass only carry and value to two-parameter reducers
This commit is contained in:
parent
d4f1130077
commit
4fe9da0167
@ -25,7 +25,6 @@ use function Kadet\Functional\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;
|
||||
|
||||
/**
|
||||
* Returns the first value for which `$predicate($value, $key)` is truthy, or the first value without a predicate.
|
||||
@ -288,6 +287,8 @@ function max(?callable $selector = null): \Closure
|
||||
/**
|
||||
* Folds the collection into a single value with `$fn($carry, $value, $key)`, starting from `$initial`.
|
||||
*
|
||||
* Internal functions (e.g. `max(...)`) and functions declaring two parameters get only `($carry, $value)`.
|
||||
*
|
||||
* @template TKey = mixed
|
||||
* @template TValue = mixed
|
||||
* @template TCarry = mixed
|
||||
@ -299,8 +300,8 @@ function max(?callable $selector = null): \Closure
|
||||
*/
|
||||
function reduce(callable $fn, mixed $initial = null): \Closure
|
||||
{
|
||||
// The reducer takes the carry first, so it is compiled without the ($value, $key) adaptation.
|
||||
$fn = compile($fn);
|
||||
// The reducer takes the carry first: an internal one, or one declaring two parameters, gets ($carry, $value).
|
||||
$fn = callback($fn, 2);
|
||||
|
||||
return static function (iterable $data) use ($fn, $initial) {
|
||||
$carry = $initial;
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
|
||||
use Ds\Map;
|
||||
use Ds\Seq;
|
||||
use Kadet\Functional as f;
|
||||
use Kadet\Functional\Collections as c;
|
||||
use Kadet\Functional\Exception\EmptyCollectionException;
|
||||
|
||||
@ -204,6 +205,24 @@ class QueriesTest extends \PHPUnit\Framework\TestCase
|
||||
$this->assertNull(c\reduce(fn ($carry, $v) => $v)([]));
|
||||
}
|
||||
|
||||
public function testReduceWithInternalFunctionGetsCarryAndValueOnly()
|
||||
{
|
||||
$this->assertSame(2, c\reduce(max(...), 0)([5 => 1, 9 => 2]));
|
||||
}
|
||||
|
||||
public function testReduceWithDecoratedTwoParameterClosureGetsCarryAndValueOnly()
|
||||
{
|
||||
$calls = [];
|
||||
$reducer = f\memoize(function ($carry, $v) use (&$calls) {
|
||||
$calls[] = func_get_args();
|
||||
|
||||
return $carry + $v;
|
||||
});
|
||||
|
||||
$this->assertSame(3, c\reduce($reducer, 0)(['a' => 1, 'b' => 2]));
|
||||
$this->assertSame([[0, 1], [1, 2]], $calls);
|
||||
}
|
||||
|
||||
public function testSum()
|
||||
{
|
||||
$this->assertSame(6, c\sum()([1, 2, 3]));
|
||||
|
||||
Loading…
Reference in New Issue
Block a user