Cowboy
Cowboy

Reputation: 272

How to add array if key value is same

Hi i having difficulty to trace an multi dimensional array.

[
    0 => array:7 [
        "date" => "2016-01-19"
        "placement_id" => 1
        "requests" => 18
        "revenue" => 1
    ],
    1 => array:7 [
        "date" => "2016-01-19"
        "placement_id" => 1
        "requests" => 2
        "revenue" => 0.2
    ]
];

if placement_id are same i want resulted array:

        1 => array:7 [
            "date" => "2016-01-19"
            "placement_id" => 1
            "requests" => 20
            "revenue" => 1.2
        ]

Upvotes: 0

Views: 122

Answers (2)

Ryan Vincent
Ryan Vincent

Reputation: 4513

The requirement is to produce an output array that has:

  • Items with the same 'placement_id' having the 'requests' and revenue summed.
  • The key of the entry in the output array will be be the 'placement_id'.

That means that the output array will be smaller that the input array.

I decided to use the array_reduce function. There is no special reason, foreach loops work fine. It isn't any more efficient. It is just different.

The important point about array_reduce is that the $carry (accumulator) can be an array...

Working example at Eval.in

The code:

$outArray = array();

$outArray = array_reduce($src,
                  function($carry, $item)  { // accumulate values if possible

                      $carryKey = $item['placement_id']; // array key

                      if (isset($carry[$carryKey])) { // accumulate values

                          $carry[$carryKey]['requests'] += $item['requests'];
                          $carry[$carryKey]['revenue'] += $item['revenue'];

                      } else { // is new - add to the output...

                          $carry[$carryKey] = $item;
                      }
                      return $carry;
                  },
                  array() /* accumulator ($carry) is an internal variable */);

Output Array:

array (2) [
    '1' => array (4) [
        'date' => string (10) "2016-01-19"
        'placement_id' => integer 1
        'requests' => integer 20
        'revenue' => float 1.2
    ]
    '666' => array (4) [
        'date' => string (10) "2016-04-01"
        'placement_id' => integer 666
        'requests' => integer 266
        'revenue' => float 666.20000000000005
    ]
]

Test Data:

$src = array(
    0 => array(
        "date" => "2016-01-19",
        "placement_id" => 1,
        "requests" => 18,
        "revenue" => 1,
    ),
    1 => array(
        "date" => "2016-04-01",
        "placement_id" => 666,
        "requests" => 266,
        "revenue" => 666.2,
    ),
    2 => array(
        "date" => "2016-01-19",
        "placement_id" => 1,
        "requests" => 2,
        "revenue" => 0.2,
    ),
);

Upvotes: 2

Tommy
Tommy

Reputation: 391

Taking that $arr parameter is the array that you show, we could create a function like this to look for duplicates ids and aggregate them. The $output array will return the results.

public function checkArray($arr) {

    $output = array();
    $deleted = array();
    foreach($arr as $key => $value){
        if (!in_array($key, $deleted)) {
            $entry = array();
            $entry['date'] = $value['date'];
            $entry['placement_id'] = $value['placement_id'];
            $entry['requests'] = $value['requests'];
            $entry['revenue'] = $value['revenue'];
            foreach($arr as $key2 => $value2){
                if($key != $key2 && $value['placement_id'] == $value2['placement_id']){
                    $entry['requests'] += $value2['requests'];
                    $entry['revenue'] += $value2['revenue'];
                    $deleted[] = $key2;
                }
            }
            $output[] = $entry;
         }
    }
    return $output;
}

Upvotes: 1

Related Questions