sum specific values in a multidimensional array (php)

I got a multidimensional array like this:

Totalarray
(
[0] => Array
    (
        [city] => NewYork
        [cash] => 1000
    )

[1] => Array
    (
        [city] => Philadelphia
        [cash] => 2300
    )

[2] => Array
    (
        [city] => NewYork
        [cash] => 2000
    )
)

and I'd like to sum the value [cash] of the sub-arrays who got the same value[city] and obtain an array like this:

Totalarray
(
[0] => Array
    (
        [city] => NewYork
        [cash] => 3000
    )

[1] => Array
    (
        [city] => Philadelphia
        [cash] => 2300
    )
)

How can I do it?


Use function array_reduce() to combine the items having the same city:

$input = array(
    array('city' => 'NewYork',      'cash' => '1000'),
    array('city' => 'Philadelphia', 'cash' => '2300'),
    array('city' => 'NewYork',      'cash' => '2000'),
);

$output = array_reduce(
    // Process the input list
    $input,
    // Add each $item from $input to $carry (partial results)
    function (array $carry, array $item) {
        $city = $item['city'];
        // Check if this city already exists in the partial results list
        if (array_key_exists($city, $carry)) {
            // Update the existing item
            $carry[$city]['cash'] += $item['cash'];
        } else {
            // Create a new item, index by city
            $carry[$city] = $item;
        }
        // Always return the updated partial result
        return $carry;
    },
    // Start with an empty list
    array()
);

Using any more than one loop (or looping function) to sum the values is inefficient.

Here is a method that uses temporary keys to build the result array and then reindexes the result array after the loop terminates.

New Code: (Demo) with no iterated function calls thanks to the "null coalescing operator"

foreach ($array as $row) {
    $result[$row['city']] = [
        'city' => $row['city'],
        'cash' => ($result[$row['city']]['cash'] ?? 0) + $row['cash']
    ];
}
var_export(array_values($result));

Old Code: (Demo)

foreach($array as $a){
    if(!isset($result[$a['city']])){
        $result[$a['city']] = $a;  // store temporary city-keyed result array (avoid Notices)
    }else{
        $result[$a['city']]['cash'] += $a['cash'];  // add current value to previous value
    }
}
var_export(array_values($result));  // remove temporary keys

Output:

array (
  0 => 
  array (
    'city' => 'NewYork',
    'cash' => 3000,
  ),
  1 => 
  array (
    'city' => 'Philadelphia',
    'cash' => 2300,
  ),
)