PHP - 如果键匹配则多维数组求和值[重复]

问题描述 投票:0回答:3

我有一个多维数组,想“汇总/减少”它,以便将与键匹配的所有值相加,其余值保持原样:

$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”始终保持不变,我将其包含在数组中,因为然后我将使用结果数组插入数据库

php arrays multidimensional-array sum grouping
3个回答
3
投票

您可以使用 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));

编辑: 忘记添加初始数组,已修复,现在应该可以工作


1
投票

这对我来说看起来很可靠,尽管循环中存在语法错误,并且您可以减少

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');

1
投票

您可以使用这样的辅助数组

$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;
}
© www.soinside.com 2019 - 2024. All rights reserved.