【问题标题】:Search for duplicates, if found sum values搜索重复项,如果找到总和值
【发布时间】:2019-03-21 12:49:54
【问题描述】:

我有这个数组:

$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
    ]
];

返回应该是:

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

我试过这样:

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

这个想法是,如果除总计之外的所有字段都是相同的,则将总计添加到具有相同字段的现有总计中。请帮我。提前谢谢,对不起我的英语

【问题讨论】:

  • 您需要遍历每个数组项并比较日期、部门和国家/地区以查看它们是否相同,然后添加总数。然后将该信息放入一个新的数组项中并删除 2 个旧的。也许有更简单的方法。

标签: php php-7


【解决方案1】:

您可以通过循环遍历您的数组,将每个元素的所有其他值(datedepartmentcountry)与之前看到的值进行比较,然后在匹配时将总数相加。此代码使用serialize 生成其他值的组合键以进行比较:

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

输出:

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

通过使用复合键作为$output数组的索引,我们可以简化这段代码,我们只需要在循环后使用array_values重新索引$output数组:

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

输出与以前相同。 Demo on 3v4l.org

【讨论】:

  • 不错的答案!这条线有什么作用? $output[] = array_merge($value, array('total' => $total));
  • @dmikester1 因为我将total 值从$value 数组中取出,以便从中生成复合键,所以我必须将其放回存储到@ 中的值中987654338@ 数组,所以当我们看到复合键第一次出现时,就有一个总数。
  • unset 和 serialize 是一种在这种情况下确保唯一性的利器!很好的答案
【解决方案2】:

您也可以尝试此方法,因为它不涉及合并等大量内存密集型操作,尤其是在处理大量数据时:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-07
    • 2019-03-28
    • 2012-11-08
    • 1970-01-01
    • 2017-08-02
    • 2018-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多