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\extremum;
|
||||||
use function Kadet\Functional\Collections\Internal\firstOf;
|
use function Kadet\Functional\Collections\Internal\firstOf;
|
||||||
use function Kadet\Functional\Collections\Internal\reversedEntries;
|
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.
|
* 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`.
|
* 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 TKey = mixed
|
||||||
* @template TValue = mixed
|
* @template TValue = mixed
|
||||||
* @template TCarry = mixed
|
* @template TCarry = mixed
|
||||||
@ -299,8 +300,8 @@ function max(?callable $selector = null): \Closure
|
|||||||
*/
|
*/
|
||||||
function reduce(callable $fn, mixed $initial = 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.
|
// The reducer takes the carry first: an internal one, or one declaring two parameters, gets ($carry, $value).
|
||||||
$fn = compile($fn);
|
$fn = callback($fn, 2);
|
||||||
|
|
||||||
return static function (iterable $data) use ($fn, $initial) {
|
return static function (iterable $data) use ($fn, $initial) {
|
||||||
$carry = $initial;
|
$carry = $initial;
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
use Ds\Map;
|
use Ds\Map;
|
||||||
use Ds\Seq;
|
use Ds\Seq;
|
||||||
|
use Kadet\Functional as f;
|
||||||
use Kadet\Functional\Collections as c;
|
use Kadet\Functional\Collections as c;
|
||||||
use Kadet\Functional\Exception\EmptyCollectionException;
|
use Kadet\Functional\Exception\EmptyCollectionException;
|
||||||
|
|
||||||
@ -204,6 +205,24 @@ class QueriesTest extends \PHPUnit\Framework\TestCase
|
|||||||
$this->assertNull(c\reduce(fn ($carry, $v) => $v)([]));
|
$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()
|
public function testSum()
|
||||||
{
|
{
|
||||||
$this->assertSame(6, c\sum()([1, 2, 3]));
|
$this->assertSame(6, c\sum()([1, 2, 3]));
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user