如何在Laravel的array_reduce函数中添加条件,仅对选中项求和?
问题
我拥有一个多维数组,希望在特定条件下对相同tax_account_id的金额进行求和。数组示例如下:
$input_taxes = [ [ "tax_account_id" => 65, "checkbox" => false, "amount" => "13950.89", ], [ "tax_account_id" => 64, "checkbox" => 0, "amount" => "1920.70", ] ];
我使用array_reduce实现求和,现有代码如下:
$result = array_reduce($input_taxes, function ($carry, $item) { if (! isset($carry[$item['tax_account_id']])) { $chart_of_account = ChartOfAccount::where('id', $item['tax_account_id']) ->first() ->name; $carry[$item['tax_account_id']] = [ 'tax_account_id' => $item['tax_account_id'], 'amount_to_apply' => $item['amount_to_apply'], 'chart_of_account' => $chart_of_account ]; } else { $carry[$item['tax_account_id']]['amount_to_apply'] += $item['amount_to_apply']; } return $carry; });
当前代码会对所有项进行求和,无论checkbox是否选中。我希望添加条件:仅当checkbox处于选中状态(true或1)时,才对相同tax_account_id的金额进行累加。我曾尝试在if和else语句内添加条件但未成功,请问如何在array_reduce中正确添加该条件?
解决方案
只需要在处理每一项前先判断checkbox是否处于选中状态,未选中的项直接跳过,不参与求和逻辑。另外注意原代码里的amount_to_apply对应输入数组的键应该是amount,这里得修正过来,还要给array_reduce传初始空数组,避免carry初始为null的问题。
修改后的完整代码如下:
$result = array_reduce($input_taxes, function ($carry, $item) { // 统一判断checkbox是否选中,true、1都会被识别为选中状态 $isChecked = filter_var($item['checkbox'], FILTER_VALIDATE_BOOLEAN); if (!$isChecked) { // 未选中直接返回当前结果集合,不做处理 return $carry; } $taxId = $item['tax_account_id']; // 把字符串金额转成浮点型,避免字符串相加出问题 $amount = (float)$item['amount']; if (!isset($carry[$taxId])) { // 第一次遇到这个tax_account_id,查询账户名称并初始化 $chartOfAccount = ChartOfAccount::where('id', $taxId)->first(); // 加个判断防止查不到数据报错 $accountName = $chartOfAccount ? $chartOfAccount->name : '未知账户'; $carry[$taxId] = [ 'tax_account_id' => $taxId, 'amount_to_apply' => $amount, 'chart_of_account' => $accountName ]; } else { // 已经存在该账户,直接累加金额 $carry[$taxId]['amount_to_apply'] += $amount; } return $carry; }, []); // 必须传入初始空数组,确保carry一开始是数组类型
关键细节说明:
- 用
filter_var做选中判断更稳妥,能兼容true/false、1/0甚至字符串形式的"1"/"0"。 - 字符串转浮点型是因为输入的
amount是字符串,直接相加会变成字符串拼接,结果完全错误。 - 给
array_reduce传初始值[]很重要,不然第一次处理时carry是null,isset($carry[$taxId])会触发报错。 - 查账户时加了空值判断,防止数据库里没有对应ID的记录导致调用
->name时报错。
内容的提问来源于stack exchange,提问作者Angel
相关产品推荐
相关产品推荐

