Skip to content

Commit

Permalink
[8.x] Add reduceMany to Collections (laravel#39078)
Browse files Browse the repository at this point in the history
* [8.x] Add `reduceMany` to Collections

* StyleCI

* StyleCI

* Update EnumeratesValues.php

Co-authored-by: Taylor Otwell <[email protected]>
  • Loading branch information
2 people authored and victorvilella committed Oct 12, 2021
1 parent b4b8434 commit 7199d8c
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
28 changes: 28 additions & 0 deletions src/Illuminate/Collections/Traits/EnumeratesValues.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use JsonSerializable;
use Symfony\Component\VarDumper\VarDumper;
use Traversable;
use UnexpectedValueException;

/**
* @property-read HigherOrderCollectionProxy $average
Expand Down Expand Up @@ -744,6 +745,33 @@ public function reduce(callable $callback, $initial = null)
return $result;
}

/**
* Reduce the collection to multiple aggregate values.
*
* @param callable $callback
* @param mixed ...$initial
* @return array
*
* @throws \UnexpectedValueException
*/
public function reduceMany(callable $callback, ...$initial)
{
$result = $initial;

foreach ($this as $key => $value) {
$result = call_user_func_array($callback, array_merge($result, [$value, $key]));

if (! is_array($result)) {
throw new UnexpectedValueException(sprintf(
"%s::reduceMany expects reducer to return an array, but got a '%s' instead.",
class_basename(static::class), gettype($result)
));
}
}

return $result;
}

/**
* Reduce an associative collection to a single value.
*
Expand Down
35 changes: 35 additions & 0 deletions tests/Support/SupportCollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use ReflectionClass;
use stdClass;
use Symfony\Component\VarDumper\VarDumper;
use UnexpectedValueException;

class SupportCollectionTest extends TestCase
{
Expand Down Expand Up @@ -3902,6 +3903,40 @@ public function testReduceWithKeys($collection)
}));
}

/**
* @dataProvider collectionClassProvider
*/
public function testReduceMany($collection)
{
$data = new $collection([-1, 0, 1, 2, 3, 4, 5]);

[$sum, $max, $min] = $data->reduceMany(function ($sum, $max, $min, $value) {
$sum += $value;
$max = max($max, $value);
$min = min($min, $value);

return [$sum, $max, $min];
}, 0, PHP_INT_MIN, PHP_INT_MAX);

$this->assertEquals(14, $sum);
$this->assertEquals(5, $max);
$this->assertEquals(-1, $min);
}

/**
* @dataProvider collectionClassProvider
*/
public function testReduceManyThrowsAnExceptionIfReducerDoesNotReturnAnArray($collection)
{
$data = new $collection([1]);

$this->expectException(UnexpectedValueException::class);

$data->reduceMany(function () {
return false;
}, null);
}

/**
* @dataProvider collectionClassProvider
*/
Expand Down

0 comments on commit 7199d8c

Please sign in to comment.