12

So I have this associative array (dump done with kint)

dump done with Kint d

Instead of having the key "Conference" repeating 3 times. I want to have it just once and sum the 3 values into one in order to have something like:

Conference : 4534

And same thing for all other keys that are repeating..

Is there a native function that can do that ?

5 Answers 5

34

You can try

$data = array(
  0 => array(
    'event' => 'Conference',
    'budget' => 3700,
  ),
  1 => array(
    'event' => 'Conference',
    'budget' => 500,
  ),
  2 => array(
    'event' => 'Showroom',
    'budget' => 1000,
  ),
  3 => array(
    'event' => 'Mission Chez client',
    'budget' => 2000,
  ),
  4 => array(
    'event' => 'Séminaire',
    'budget' => 700,
  ),
  5 => array(
    'event' => 'Livraison',
    'budget' => 4000,
  ),
  6 => array(
    'event' => 'Conference',
    'budget' => 334,
  ),
);

$sum = array_reduce($data, function ($a, $b) {
    isset($a[$b['event']]) ? $a[$b['event']]['budget'] += $b['budget'] : $a[$b['event']] = $b;  
    return $a;
});


print_r(array_values($sum));

Output

Array
(
    [0] => Array
        (
            [event] => Conference
            [budget] => 4534
        )

    [1] => Array
        (
            [event] => Showroom
            [budget] => 1000
        )

    [2] => Array
        (
            [event] => Mission Chez client
            [budget] => 2000
        )

    [3] => Array
        (
            [event] => Séminaire
            [budget] => 700
        )

    [4] => Array
        (
            [event] => Livraison
            [budget] => 4000
        )

)
Sign up to request clarification or add additional context in comments.

5 Comments

It preserves the second key "budget" but not the first one "event", it gives this: link
I really need to keep the same structure but sum values with the same key
Thx Baba, it is exactly what I'm looking for, but it seems that the values are sumed twice: 1- original array link 2- array after sum function link 'Livraison' for example should have 4000, any idea why It has 8000 ?
I can't work with image ... use print_r of the original array and add it to pastebin
Original array link . Results array link
5

A simple suggestion:

$results = array();
foreach ($budgetByEventTemp as $value)
{
  if( ! isset($results[$value['event']]) )
  {
     $results[$value['event']] = 0;
  }

  $results[$value['event']] += $value['budget'];

}

var_dump($results);

Update according to comments

You can run over them again:

foreach($results as $key => $value)
{
  $structured_results[] = array('event' => $key, 'budget' => $value);
}

var_dump($structured_results);

3 Comments

Thank you for the suggestion, but that would not preserve the keys of the array (event and budget)
I fail to see why it should, when you wan't to sum up the values?
This array is encoded via json and sent to be cooked somewhere else, so I need to preserve the same structure and just sum values with the same key
1
$sumArray = array();

foreach ($myArray as $k=>$subArray) {
foreach ($subArray as $id=>$value) {
  $sumArray[$id]+=$value;
  }
}

print_r($sumArray);

1 Comment

This unexplained answer generates warnings/errors. Proof: 3v4l.org/CHfSE
0

This option will group and sum values of all repeated indexes in an array.

Code here :

$aValues[]=array("nametogroup",10);
$aValues[]=array("nametogroup",20);
$aValues[]=array("nametogroup2",30);
$aValues[]=array("nametogroup2",20);
echo var_dump($aValues); // array before grouping
foreach ($aValues as  $id=>$value) 
{
  $a2sum["{$value[0]}"]=$value[1] + $a2sum["{$value[0]}"];
}
echo var_dump($a2sum); //array after group and adding values

This will result into:

array
0 => 
array
  0 => string nametogroup (length=11)
  1 => int 10
1 => 
array
  0 => string nametogroup (length=11)
  1 => int 20
2 => 
array
  0 => string nametogroup2 (length=12)
  1 => int 30
3 => 
array
  0 => string nametogroup2 (length=12)
  1 => int 20

array
nametogroup => int 30
nametogroup2 => int 50

Comments

0

To iterate a set of data and return a potentially smaller set of data, array_reduce() is a wise "functional" choice. Here is a slight variation on @Baba's answer using a null coalescing operator and a more intuitive variable naming convention.

Code: (Demo)

var_export(
    array_reduce(
        $data,
        function ($carry, $row) {
            $carry[$row['event']] = ($carry[$row['event']] ?? 0) + $row['budget'];
            return $carry;
        }
    )
);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.