Search for duplicates, if found sum values

荒凉一梦 提交于 2021-02-05 05:28:51

问题


I have this array :

$data = [
    0 => [
       'date'       => '2018-09-12',
       'department' => 12,
       'country'    => 14,
       'total'      => 12
    ],
    1 => [
       'date'       => '2018-09-12',
       'department' => 12,
       'country'    => 14,
       'total'      => 18
    ],
    2 => [
       'date'       => '2018-09-12',
       'department' => 12,
       'country'    => 15,
       'total'      => 10
    ]
];

The return should be :

$return = [
   0 => [
       'date'       => '2018-09-12',
       'department' => 12,
       'country'    => 14,
       'total'      => 30
   ],
   1 => [
       'date'       => '2018-09-12',
       'department' => 12,
       'country'    => 15,
       'total'      => 10
   ]
];

I tried like this :

foreach ($data as $value) {
     if(!in_array($value, $data)) {
         $result[] = $data;
     }
}

The idea is, if all fields except total are indentical, then add total to the existing total with the same fields. Please help me. Thx in advance and sorry for my english


回答1:


You can do this by looping through your array, comparing all the other values of each element (date, department and country) with previously seen values and summing the totals when you get a match. This code uses serialize to generate a composite key of the other values for comparison:

$output = array();
$keys = array();
foreach ($data as $value) {
    $total = $value['total'];
    unset($value['total']);
    $key = serialize($value);
    if (($k = array_search($key, $keys)) !== false) {
        $output[$k]['total'] += $total;
    }
    else {
        $keys[] = $key;
        $output[] = array_merge($value, array('total' => $total));
    }
}
print_r($output);

Output:

Array (
    [0] => Array (
        [date] => 2018-09-12
        [department] => 12
        [country] => 14
        [total] => 30 
    )
    [1] => Array (
        [date] => 2018-09-12
        [department] => 12
        [country] => 15
        [total] => 10
     ) 
)

Demo on 3v4l.org

By using the composite key as the index into the $output array, we can simplify this code, we just need to use array_values after the loop to re-index the $output array:

$output = array();
foreach ($data as $value) {
    $v = $value;
    unset($v['total']);
    $key = serialize($v);
    if (isset($output[$key])) {
        $output[$key]['total'] += $value['total'];
    }
    else {
        $output[$key] = $value;
    }
}
$output = array_values($output);
print_r($output);

Output is the same as before. Demo on 3v4l.org




回答2:


You can also try this method as it doesn't involve much memory intensive operations such as merging, especially while working with large amount of data:

$new_data=[];
foreach($data as $key=>$value){
    $i=array_search($value["date"],array_column($new_data,"date"));
    if(($i!==false)&&($new_data[$i]["department"]==$value["department"])&&($new_data[$i]["country"]==$value["country"])){
        $new_data[$i]["total"]+=$value["total"];
    }
    else{
        $new_data[]=$value;
    }
}
print_r($new_data);


来源:https://stackoverflow.com/questions/55280844/search-for-duplicates-if-found-sum-values

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