Home > OS >  Laravel/PHP: Add another condition in array_reduce function
Laravel/PHP: Add another condition in array_reduce function

Time:11-15

I have multidimensional array and I want to sum all the same value with a certain condition.

Here's what my array looks like

$input_taxes = [
    [
        "tax_account_id" => 65,
        "checkbox" => false,
        "amount" => "13950.89",
    ],
    [
        "tax_account_id" => 64,
        "checkbox" => 0,
        "amount" => "1920.70",
    ]
];

What I've researched, they used array_reduce. Below is my code:

$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; 
});

Currently, it will sum all the same values even though it is not checked. Now I want to put a condition where it should be check first before it will sum all the same values.

NOTE: I already tried to put an if statement inside of both if and else statement but unfortunately it didn't work.

Question: How can I add a certain condition within array_reduce?

CodePudding user response:

The check must be inserted at the beginning of your function.

$result = array_reduce($input_taxes, function ($carry, $item) {
    if (!$item['checkbox']) {
        return $carry;
    }

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

I can also offer a small optimization to reduce the number of requests to the database

$chartOfAccountNames = UserProfile::query()
    ->whereIn('id', array_column($input_taxes, 'tax_account_id'))
    ->pluck('name', 'id')
    ->toArray();

$result = array_reduce($input_taxes, static function ($carry, $item) use ($chartOfAccountNames) {
    if (!$item['checkbox']) {
        return $carry;
    }
    if (isset($carry[$item['tax_account_id']])) {
        $carry[$item['tax_account_id']]['amount_to_apply']  = $item['amount'];

        return $carry;
    }

    $carry[$item['tax_account_id']] = [
        'tax_account_id' => $item['tax_account_id'],
        'amount_to_apply' => $item['amount'],
        'chart_of_account' => $chartOfAccountNames[$item['tax_account_id']],
    ];

    return $carry;
});
  • Related