我有一个多维数组,想“汇总/减少”它,以便将与键匹配的所有值相加,其余值保持原样:
$payments = [
['bookingId' => 1, 'vendorId' => 3, 'amount' => 50],
['bookingId' => 1, 'vendorId' => 3, 'amount' => 85],
['bookingId' => 1, 'vendorId' => 4, 'amount' => 14],
];
预期结果:
$payments = [
['bookingId' => 1, 'vendorId' => 3, 'amount' => 135],
['bookingId' => 1, 'vendorId' => 4, 'amount' => 14],
];
我知道我可以使用循环来实现这一点,只是想知道是否有更好的方法:
$output = [];
foreach($payments as $value) {
if(!array_key_exists($value['vendorId', $output))
$output[$value['vendorId'] = [
'bookingId' => $value['bookingId'],
'vendorId' => $value['vendorId'],
'amount' => $value['amount']
];
else
$output[$value['vendorId']['amount'] += $value['amount'];
}
$payments = array_values($output);
在此示例中,“bookingId”始终保持不变,我将其包含在数组中,因为然后我将使用结果数组插入数据库
您可以使用 array_reduce 获得几乎相同的结果:
$payments = [
['bookingId' => 1, 'vendorId' => 3, 'amount' => 50],
['bookingId' => 1, 'vendorId' => 3, 'amount' => 85],
['bookingId' => 1, 'vendorId' => 4, 'amount' => 14],
];
$result = array_reduce(
$payments,
function(array $carry, array $payment): array {
$prev = $carry[$payment['vendorId']]['amount'] ?? 0;
$carry[$payment['vendorId']] = $payment;
$carry[$payment['vendorId']]['amount'] += $prev;
return $carry;
},
[]
);
var_dump(array_values($result));
编辑: 忘记添加初始数组,已修复,现在应该可以工作
这对我来说看起来很可靠,尽管循环中存在语法错误,并且您可以减少
if
语句中的代码相当多,但您在那里工作得太辛苦了。
<?php
$payments = [
['bookingId' => 1, 'vendorId' => 3, 'amount' => 50],
['bookingId' => 1, 'vendorId' => 3, 'amount' => 85],
['bookingId' => 1, 'vendorId' => 4, 'amount' => 14],
];
$expected = [
['bookingId' => 1, 'vendorId' => 3, 'amount' => 135],
['bookingId' => 1, 'vendorId' => 4, 'amount' => 14],
];
$output = [];
foreach ($payments as $value)
{
if (!array_key_exists($value['vendorId'], $output))
{
$output[$value['vendorId']] = $value;
}
else
{
$output[$value['vendorId']]['amount'] += $value['amount'];
}
}
$payments = array_values($output);
assert($payments == $expected, 'Output should match expected results');
您可以使用这样的辅助数组
$aHelper = [];
foreach($payments as $payment) {
$bookingId = $payment['bookingId'];
$vendorId = $payment['vendorId'];
$amount = $payment['amount'];
if (!isset($aHelper[ $bookingId ][ $vendorId ])) {
$aHelper[ $bookingId ][ $vendorId ] = 0;
}
$aHelper[ $bookingId ][ $vendorId ] += $amount;
}