0

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
        ]
1
  • please share what you have you tried Commented Jan 20, 2016 at 11:30

2 Answers 2

2

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,
    ),
);
Sign up to request clarification or add additional context in comments.

1 Comment

Its pretty neat and short, Thanks Ryan :)
1

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

3 Comments

Thank u so much tommy
@Cowboy i just hope that you take your time to understand the solution and not just doing copy&paste :)
Thank you for ur concern !! I will digest it Tommy:)

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.