April 22, 2018 —John Koster
The reduce
method is to reduce a collection into only one item. It does this by iterating over the collection and applying the $callback
function on each element. The $callback
function should define two parameters: $carry
and $item
. The $carry
variable will be initialized to the previous result of the $callback
function and the $item
variable will contain the actual collection item relevant to the current iteration. The $reduce
method also defines a $initial
parameter.
Whatever value is given to $initial
will become the value of the $carry
variable on the first call to the $callback
function. If there are no items in the collection, the $initial
value is returned as the value of reduce
.
The reduce
method is similar in behavior to PHP's array_reduce
function.
1public function reduce(2 callable $callback,3 $initial = null4);
The following examples will demonstrate some of the most basic uses of the reduce
method. The returned value of the method call will appear above the method call as a comment.
1use Illuminate\Support\Collection; 2 3// Create a new collection instance. 4$collection = new Collection([ 5 1, 2, 3, 4, 5 6]); 7 8// 15 9$sum = $collection->reduce(function($carry, $item) {10 return $carry + $item;11});12 13// -1514$difference = $collection->reduce(function($carry, $item) {15 return $carry - $item;16});
The following sample will show how to get the product of each item in the collection. It will also prove a good use case for the $initial
parameter:
1// 02$product = $collection->reduce(function($carry, $item) {3 return $carry * $item;4});
The above example returns 0
which might not seem obvious when the expected answer is 120
. However, the $initial
is used as the $carry
argument for the first iteration of the $callback
function. The $initial
value is null
by default. When null
is used for mathematical operations in PHP, it is treated as the value 0
:
1// 02$value = intval(null);
Because of this, the multiplication looks like this for each iteration (the result will become the carry value for the next iteration):
Iteration | Carry | Item | Result |
---|---|---|---|
1 | 0 (from $initial ) |
1 |
0 |
2 | 0 |
2 |
0 |
3 | 0 |
3 |
0 |
4 | 0 |
4 |
0 |
5 | 0 |
5 |
0 |
The result is 0
, because multiplying any value by zero will result in zero (the multiplication property of zero). To get the desired answer, the $initial
value must be set to 1
:
1// 1202$product = $collection->reduce(function($carry, $item) {3 return $carry * $item;4}, 1);
The following table shows the iterations using the change made above:
Iteration | Carry | Item | Result |
---|---|---|---|
1 | 1 (from $initial ) |
1 |
1 |
2 | 1 |
2 |
2 |
3 | 2 |
3 |
6 |
4 | 6 |
4 |
24 |
5 | 24 |
5 |
120 |
∎
The following amazing people help support this site and my open source projects ♥️
If you're interesting in supporting my work and want to show up on this list, check out my GitHub Sponsors Profile.