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

ぃ、小莉子 提交于 2021-01-28 06:03:20

问题


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
        )
) 

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



回答2:


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,
  ),
  ...
)



回答3:


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


来源:https://stackoverflow.com/questions/47298189/how-to-group-subarray-data-using-multiple-column-values-and-individually-sum-the

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!