Skip to content

Commit

Permalink
Allow closures for sum()
Browse files Browse the repository at this point in the history
  • Loading branch information
aimeos committed Jul 30, 2024
1 parent 1a3559c commit 71fb573
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 6 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5093,10 +5093,10 @@ Map::from( ['a', 'b'] )->suffix( function( $item, $key ) {
Returns the sum of all integer and float values in the map.

```php
public function sum( string $col = null ) : float
public function sum( $col = null ) : float
```

* @param **string|null** `$col` Key in the nested array or object to sum up
* @param **Closure|string|null** `$col` Closure, key in the nested array or object to sum up
* @return **float** Sum of all elements or 0 if there are no elements in the map

This does also work to map values from multi-dimensional arrays by passing the keys
Expand All @@ -5118,6 +5118,9 @@ Map::from( [['p' => 30], ['p' => 50], ['p' => 10]] )->sum( 'p' );

Map::from( [['i' => ['p' => 30]], ['i' => ['p' => 50]]] )->sum( 'i/p' );
// 80

Map::from( [30, 50, 10] )->sum( fn( $val, $key ) => $val < 50 ? $val : 0 );
// 40
```


Expand Down
20 changes: 16 additions & 4 deletions src/Map.php
Original file line number Diff line number Diff line change
Expand Up @@ -4658,10 +4658,11 @@ public function suffix( $suffix, int $depth = null ) : self
* Map::from( [1, 'sum', 5] )->sum();
* Map::from( [['p' => 30], ['p' => 50], ['p' => 10]] )->sum( 'p' );
* Map::from( [['i' => ['p' => 30]], ['i' => ['p' => 50]]] )->sum( 'i/p' );
* Map::from( [30, 50, 10] )->sum( fn( $val, $key ) => $val < 50 ? $val : 0 );
*
* Results:
* The first line will return "9", the second one "6", the third one "90"
* and the last one "80".
* the forth on "80" and the last one "40".
*
* NULL values are treated as 0, non-numeric values will generate an error.
*
Expand All @@ -4670,12 +4671,23 @@ public function suffix( $suffix, int $depth = null ) : self
* to get "val" from ['key1' => ['key2' => ['key3' => 'val']]]. The same applies to
* public properties of objects or objects implementing __isset() and __get() methods.
*
* @param string|null $key Key or path to the values in the nested array or object to sum up
* @param Closure|string|null $col Closure, key or path to the values in the nested array or object to sum up
* @return float Sum of all elements or 0 if there are no elements in the map
*/
public function sum( string $key = null ) : float
public function sum( $col = null ) : float
{
$vals = $key !== null ? $this->col( $key )->toArray() : $this->list();
if( $col instanceof \Closure )
{
$vals = [];
foreach( $this->list() as $key => $val ) {
$vals[] = $col( $val, $key );
}
}
else
{
$vals = $col !== null ? $this->col( $col )->toArray() : $this->list();
}

return !empty( $vals ) ? array_sum( $vals ) : 0;
}

Expand Down
7 changes: 7 additions & 0 deletions tests/MapTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3074,6 +3074,13 @@ public function testSum()
}


public function testSumClosure()
{
$this->assertSame( 40.0, Map::from( [30, 50, 10] )->sum( fn( $val ) => $val < 50 ? $val : 0 ) );
$this->assertSame( 60.0, Map::from( [30, 50, 10] )->sum( fn( $val, $key ) => $key > 0 ? $val : 0 ) );
}


public function testSumPath()
{
$this->assertSame( 90.0, Map::from( [['p' => 30], ['p' => 50], ['p' => 10]] )->sum( 'p' ) );
Expand Down

0 comments on commit 71fb573

Please sign in to comment.