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.
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));
Code: (Demo) with references to avoid declaring first level grouping key and any globally scoped variables
var_export(
array_reduce(
$array,
function($result, $row) {
static $ref;
if (!isset($ref[$row['city']])) {
$ref[$row['city']] = $row;
$result[] = &$ref[$row['city']];
} else {
$ref[$row['city']]['cash'] += $row['cash'];
}
return $result;
}
)
);
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