Cananau Cristian
Cananau Cristian

Reputation: 456

Group associative elements of a 2d array by 2nd level key and sum the values of shared keys

I have an array that contains a sub-array. I want to sum the values where the key is the same and to make it in one list.

Here is my array:

$array = [ 
    ['x1' => 1, 'x2' => 3, 'y5' => 9],
    ['x1' => 3, 'x4' => 1, 'y5' => 1],
    ['x1' => 1, 'x8' => 5, 'a5' => 2],
    ['x1' => 2, 'x10' => 3, 'b5' => 5],
];

And I want to have an array like :

$newarray = [
    'x1' => 7,
    'x2' => 3,
    'x4' => 1,
    'x8' => 5,
    'x10' => 3,
    'y5' => 9,
    'y5' => 1,
    'a5' => 2
];

My try:

foreach ($array as $key => $values) {
    foreach ($values as $n_k => $n_v) { 
        $newarray[$n_k] += $n_v;
    }
}

Upvotes: 1

Views: 386

Answers (4)

Deepak singh Thakur
Deepak singh Thakur

Reputation: 299

 $input =  array( array(x1=> 1, x2 => 3, y5 => 9),
 array(x1=> 3, x4 => 1, y5 => 1),
 array(x1=> 1, x8 => 5, a5 => 2),
 array(x1=> 2, x10 => 3)
);
 $final = array();
 array_walk_recursive($input, function($item, $key) use (&$final){
     $final[$key] = isset($final[$key]) ?  $item + $final[$key] : $item;
 });
  print_r($final);

Upvotes: 0

Bruno
Bruno

Reputation: 432

That's not my question, but i've found this that can help you:

https://stackoverflow.com/a/14196064/9721446

You have to create a new array, and then for each equal keyid, you're going to add the value. Somethinkg like that i think it works. if doesn't help you, take a look at this post, that's not mine too!!!!

Associative array, sum values of the same key

Upvotes: 0

Andreas
Andreas

Reputation: 23958

You can first get all the keys from the array and use that in a array_column and array_sum to get your desired output.
This will probably have more benefit if the array is larger.

$array =  array( array("x1" => 1, "x2" => 3, "y5" => 9),
                 array("x1" => 3, "x4" => 1, "y5" => 1),
                 array("x1" => 1, "x8" => 5, "a5" => 2),
                 array("x1" => 2, "x10" => 3, "b5" => 5)
                );

$keys = [];
// get all keys used in $array
foreach($array as $subarr){
     $keys = array_merge($keys, array_keys($subarr));
}
// $keys is now: 
// array (0 => 'x1', 1 => 'x2', 2 => 'y5', 3 => 'x1', 4 => 'x4', 5 => 'y5', 6 => 'x1', 7 => 'x8', 8 => 'a5', 9 => 'x1', 10 => 'x10', 11 => 'b5')

// loop only unique keys and sum the values
foreach(array_unique($keys) as $item){
    $res[$item] = array_sum(array_column($array, $item));
}
var_dump($res);

https://3v4l.org/WaqlG

Upvotes: 1

Eddie
Eddie

Reputation: 26844

The problem is you are adding a value even if it is not defined.

You can check if not set by and init the value to 0

if ( !isset($newarray[$n_k]) ) $newarray[$n_k] = 0;

Here is the complete code:

$array =  array( array('x1'=> 1, 'x2' => 3, 'y5' => 9), array('x1'=> 3, 'x4' => 1, 'y5' => 1), array('x1'=> 1, 'x8' => 5, 'a5' => 2), array('x1'=> 2, 'x10' => 3, 'b5' => 5));
$newarray = array();

foreach($array as $key => $values){
   foreach($values as $n_k => $n_v) {   
       if ( !isset($newarray[$n_k]) ) $newarray[$n_k] = 0;
       $newarray[$n_k] += $n_v;
   }
}

This will result to:

Array
(
    [x1] => 7
    [x2] => 3
    [y5] => 10
    [x4] => 1
    [x8] => 5
    [a5] => 2
    [x10] => 3
    [b5] => 5
)

Upvotes: 2

Related Questions