Skip to content
Advertisement

Group 2D array by id column, push amount into group, and add amount to all previous amounts in group

Using array_key_exists() you would find repeated values and be able to sum them up. In my case, I am not trying to sum all the values and consolidate them into one value. What I am trying to do is to iterate through the values, group by the ac_no value and each subsequent encounter of the same ac_no value, add the new amount to all previously encountered amounts in the group.

Here’s my sample input:

$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]
];

Notice that ac_no value 100001 exists 4 times. In the result, the 100001 group should have the following elements because each absolute value is added to all previous amounts in the group:

[
    52,376.05,    # .00 + 51255.11 + abs(-500.00) + abs(-621.05)
    52,376.05,    # 51255.11 + abs(-500.00) + abs(-621.05)
    1,120.94,     # abs(-500.00) + abs(-621.05)
    621.05        # abs(-621.05)
]

My current coding attempt looks like this:

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

Advertisement

Answer

Three foreach() along with array_sum() and is_array() will do the job (I am considering negative values to be subtracted):

 $acNoWiseArray = [];
 
 //get all amounts as an array  ac_no wise
 foreach($array as $arr){
    $acNoWiseArray[$arr['ac_no']]['sum'][] = $arr['amount'];
 }
 
 
 $finalArray = [];
 foreach($acNoWiseArray as $key=>&$value){//calling by reference
    foreach($value['sum'] as $k=> $val){
        $finalArray[$key]['new_sum'][] = (is_array($value)) ? array_sum($value['sum']) : $value['sum'][$k];
        array_shift($value['sum']);
    }
 }
 
 print_r($finalArray);

Output : https://3v4l.org/duoEc

Important Update: But as I looked at your calculation closely (based on @mickmackusa comment) I found that you are ignoring the - sign and adding all values as positive. To do so do like below:

$acNoWiseArray = [];
 
 foreach($array as $arr){
    $acNoWiseArray[$arr['ac_no']]['sum'][] = $arr['amount'];
 }
 
 
 $finalArray = [];
 foreach($acNoWiseArray as $key=>&$value){
    foreach($value['sum'] as $k=> $val){
        $finalArray[$key]['new_sum'][] = (is_array($value)) ? array_sum(array_map('abs',$value['sum'])) : abs($value['sum'][$k]);
        array_shift($value['sum']);
    }
   
    
 }
 
 print_r($finalArray);

Output : https://3v4l.org/j9tkC

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement