How to group subarray data using multiple column values and individually sum the remaining column values?
Asked Answered
S

3

1

How can I group by Source and date then SUM Pageviews and revenue this array below

Array
(
    [0] => Array
        (
            [Source] => Analytics
            [Date] => 2017-10-31
            [Source] => Google
            [visits] => 6000
            [Pageviews] => 12,214
            [Revenue] => 25
        )
    [1] => Array
        (
            [Source] => Analytics
            [Date] => 2017-10-31
            [Source] => Google
            [visits] => 600
            [Pageviews] => 1015
            [Revenue] => 10
        )
    [2] => Array
          (
            [Source] => Analytics
            [Date] => 2017-10-31
            [Source] => Facebook
            [visits] => 600
            [Pageviews] => 1144
            [Revenue] => 40
        )

    [3] => Array
        (
            [Source] => Analytics
            [Date] => 2017-10-30
            [Source] => Google
            [visits] => 600
            [Pageviews] => 1144
            [Revenue] => 10
        )

    [4] => Array
         (
            [Source] => Analytics
            [Date] => 2017-10-30
            [Source] => Facebook
            [visits] => 1600
            [Pageviews] => 11,445
            [Revenue] => 5
        )
     [5] => Array
         (
            [Source] => Analytics
            [Date] => 2017-10-30
            [Source] => Facebook
            [visits] => 700
            [Pageviews] => 7,445
            [Revenue] => 8
        )
)

Expected Result

Array
(
    [0] => Array
        (
            [Source] => Analytics
            [Date] => 2017-10-31
            [Source] => Google
            [visits] => 6600
            [Pageviews] => 13,229
            [Revenue] => 35
        )
    [1] => Array
        (
            [Source] => Analytics
            [Date] => 2017-10-31
            [Source] => Facebook
            [visits] => 600
            [Pageviews] => 1144
            [Revenue] => 40
        )
    [2] => Array
        (
            [Source] => Analytics
            [Date] => 2017-10-30
            [Source] => Google
            [visits] => 600
            [Pageviews] => 1144
            [Revenue] => 10
        )
    [3] => Array
        (
            [Source] => Analytics
            [Date] => 2017-10-30
            [Source] => Facebook
            [visits] => 2,300
            [Pageviews] => 18,890
            [Revenue] => 35
        )
) 
Shire answered 15/11, 2017 at 1:59 Comment(6)
where are the codes, is this from DB? why not sum them from therePsychomancy
Users on StackOverflow will help you, after you help yourself. Do some research: meta.https://mcmap.net/q/22495/-what-do-i-need-to-read-to-understand-how-git-works-closed/1011527. Learn how to post good questions: stackoverflow.com/help/how-to-ask. And stackoverflow.com/help/mcve.Argenteuil
Please post your question with var_export() instead of print_r or var_dump. Otherwise we have to write the code to create the array on our test systems to help you. and most will simply not bother.Argenteuil
Its not in the DB, Its from API.Shire
How do you intend to differentiate between the two Source elements in each array?Surd
Yes, Actually I have to differentiate, So final result will be I know how much total revenue from each source (Facebook and Google) each dayShire
I
1

Here is the function you need. Cheers...

function combineAndSumUp ($myArray = []) {

    $finalArray = Array ();

    foreach ($myArray as $nkey => $nvalue) {

        $has = false;
        $fk = false;

        // Remove comma from numbers
        $nvalue['Pageviews'] = str_replace(",","",$nvalue["Pageviews"]);

        foreach ($finalArray as $fkey => $fvalue) {
            if ( ($fvalue['Date'] == $nvalue['Date']) && ($fvalue['Source'] == $nvalue['Source']) ) {
                $has = true;
                $fk = $fkey;
                break;
            }
        }

        if ( $has === false ) {
            $finalArray[] = $nvalue;
        } else {
            $finalArray[$fk]['visits'] += $nvalue['visits'];
            $finalArray[$fk]['Pageviews'] += $nvalue['Pageviews'];
            $finalArray[$fk]['Revenue'] += $nvalue['Revenue'];
        }

    }

    return $finalArray;
}
Incapacitate answered 15/11, 2017 at 6:8 Comment(0)
S
1

What @J.D.Pace meant by the comment:

How do you intend to differentiate between the two Source elements in each array?

is...

"Your incoming data is impossible, because you may not have two of the same key in the same level of an array. Your data shows "Source" => "Analytics" and "Source" => "Facebook" in the same subarray." ...This means that your sample input data is inaccurate.

Because we cannot know how it should be in your case AND because the Analytics value is completely worthless in respect to this task, I will provide a solution which omits these inaccurate subarray elements.

The other answers are working too hard and writing too much code. It is not necessary to write multiple/nested loops, nor to pre-sort the data. This task is very simply accomplished with a single loop by assigning "compound temporary keys" in your output array and using the output array as a "lookup array" while processing. isset() is a very fast way of determining if the current subarray contains a new group of data or if the group has been encountered before.

When finished you can optionally call array_values() to re-index the output (if needed). You may also like to re-iterate to reformat the Pageviews to include commas -- that is again at your discretion.

Code: (Demo)

$array = [
    ['Date' => '2017-10-31', 'Source' => 'Google', 'visits' => '6000', 'Pageviews' => '12,214', 'Revenue' => '25'],
    ['Date' => '2017-10-31', 'Source' => 'Google', 'visits' => '600', 'Pageviews' => '1015', 'Revenue' => '10'],
    ['Date' => '2017-10-31', 'Source' => 'Facebook', 'visits' => '600', 'Pageviews' => '1144', 'Revenue' => '40'],
    ['Date' => '2017-10-30', 'Source' => 'Google', 'visits' => '600', 'Pageviews' => '1144', 'Revenue' => '10'],
    ['Date' => '2017-10-30', 'Source' => 'Facebook', 'visits' => '1600', 'Pageviews' => '11,445', 'Revenue' => '5'],
    ['Date' => '2017-10-30', 'Source' => 'Facebook', 'visits' => '700', 'Pageviews' => '7,445', 'Revenue' => '8'],
];

foreach ($array as $subarray) {
    $tempKey = $subarray['Source'].$subarray['Date'];  // this is the compound value
    $subarray['Pageviews'] = str_replace(',', '', $subarray['Pageviews']); // get rid of meddlesome comma
    if (isset($result[$tempKey])) {
        $result[$tempKey]['visits'] += $subarray['visits'];
        $result[$tempKey]['Pageviews'] += $subarray['Pageviews'];
        $result[$tempKey]['Revenue'] += $subarray['Revenue'];
    } else {
        $result[$tempKey] = $subarray;
    }
}
var_export(array_values($result));

Output: (abridged)

array (
  0 => 
  array (
    'Date' => '2017-10-31',
    'Source' => 'Google',
    'visits' => 6600,
    'Pageviews' => 13229,
    'Revenue' => 35,
  ),
  ...
)
Santoyo answered 23/5, 2020 at 7:47 Comment(0)
A
0

Assuming there is only one Source index.

Try this:

array_multisort(array_column($arr, 'Date'), SORT_DESC,array_column($arr, 'Source'), SORT_DESC, $arr);

$new_arr = [];
$temp = ["Date"=>""];
$ctr = 0;
foreach($arr as $val) {
    if($val["Date"] == $temp["Date"] && $val["Source"] == $temp["Source"]) {
        $ctr2 = $ctr - 1;
        $new_arr[$ctr2]["visits"] += $val["visits"];
        $new_arr[$ctr2]["Pageviews"] += $val["Pageviews"];
        $new_arr[$ctr2]["Revenue"] += $val["Revenue"];
    } else {
        $new_arr[$ctr++] = $val;
    }
    $temp = $val;
}

print_r($new_arr);
Agronomy answered 15/11, 2017 at 5:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.