You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP按ac_no分组二维数组 累加后续金额绝对值至组内前置项

按ac_no分组累加金额实现方案

需求规则

使用array_key_exists()可完成重复键检测与基础值求和,但本次需求不需要将同组所有值合并为单个结果,核心规则为:
遍历数组元素按ac_no字段分组,每遇到相同ac_no的新记录时,将该条记录的amount取绝对值,累加到同组内所有已经存在的前置金额项上,最终每个原记录位置都保留对应的累加后金额。

示例输入

$array = [
     ['ac_no' => 100001, 'amount' => 0.00],
     ['ac_no' => 100001, 'amount' => 51255.11],
     ['ac_no' => 100001, 'amount' => -500.00],
     ['ac_no' => 100001, 'amount' => -621.05],
     ['ac_no' => 100002, 'amount' => .00],
     ['ac_no' => 100003, 'amount' => .00],
     ['ac_no' => 100004, 'amount' => 20714.00],
     ['ac_no' => 100004, 'amount' => 0.00]
];

预期结果(以ac_no=100001分组为例)

每个元素值为对应位置及之后所有amount绝对值的累加和:

[
    52376.05,    // 0.00 + 51255.11 + abs(-500.00) + abs(-621.05)
    52376.05,    // 51255.11 + abs(-500.00) + abs(-621.05)
    1121.05,     // abs(-500.00) + abs(-621.05) 注:示例标注1120.94为浮点数计算精度误差
    621.05       // abs(-621.05)
]

原有代码问题

原有尝试代码无法实现需求,核心问题有三点:

  • 每个ac_no分组仅保留单条记录,没有保留同组下所有原记录的位置
  • 错误对ac_no字段做数值累加,该字段为分组标识不需要参与计算
  • 没有实现新条目金额回写同组所有前置条目的逻辑
foreach ($nameAndCode as $key => $vals) {
    if (array_key_exists($vals['ac_no'], $res)) {
        $amt = abs($vals['amount']);
        $res[$vals['ac_no']]['ac_no']  += $vals['ac_no'];
        $res[$vals['ac_no']]['amount'] += $amt; 
    } else {
        $res[$vals['ac_no']]  = $vals;
    }
}

正确实现代码

采用「先分组、后倒序计算后缀和」的逻辑实现,和需求规则完全等价,性能更高:

$res = [];
$groups = [];

// 第一遍遍历:按ac_no分组,记录每组元素的原始索引和金额
foreach ($array as $idx => $item) {
    $acNo = $item['ac_no'];
    if (!array_key_exists($acNo, $groups)) {
        $groups[$acNo] = [];
    }
    $groups[$acNo][] = [
        'origin_idx' => $idx,
        'amount' => $item['amount']
    ];
}

// 第二遍遍历:逐组倒序计算累加和
foreach ($groups as $acNo => $groupItems) {
    $runningTotal = 0;
    // 从分组最后一个元素向前遍历
    for ($i = count($groupItems) - 1; $i >= 0; $i--) {
        $current = $groupItems[$i];
        $runningTotal += abs($current['amount']);
        // 将计算结果填回对应原始索引位置
        $res[$current['origin_idx']] = [
            'ac_no' => $acNo,
            'amount' => $runningTotal
        ];
    }
}

// 按原数组顺序重排结果
ksort($res);

逻辑说明

  • 第一遍遍历仅做分组归集,不做金额计算,避免遍历过程中反复修改前置项的冗余操作
  • 倒序计算后缀和的逻辑,和需求中「新条目金额累加到所有前置项」的规则完全一致:越靠前的元素,累加的后续条目越多
  • 最终输出保留原数组的键值结构和顺序,不会修改ac_no字段值

内容的提问来源于stack exchange,提问作者fagbemi ayodele

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 12:00:51