多个数组处理 当date和customer的值一样 求和 求优化方法

$a = [
  ['date' => '2017-06-9', 'customer' => 1161, 'total' => 3, 'cg' => 1],
  ['date' => '2017-06-11', 'customer' => 1163, 'total' => 8, 'cg' => 3],
  ['date' => '2017-06-14', 'customer' => 1163, 'total' => 10, 'cg' => 5],
  ['date' => '2017-06-12', 'customer' => 1163, 'total' => 4, 'cg' => 2],

];
$b = [
  ['date' => '2017-06-10', 'customer' => 1161, 'total' => 3, 'cg' => 1],
  ['date' => '2017-06-11', 'customer' => 1163, 'total' => 9, 'cg' => 2],
  ['date' => '2017-06-13', 'customer' => 1165, 'total' => 6, 'cg' => 5],
  ['date' => '2017-06-11', 'customer' => 1165, 'total' => 5, 'cg' => 2]
];


//我写了个下面的数组处理方法,有更好的方法吗???

//代码开始

function merge_arr($myArray, $subArr){
    $sArray = $zArray =  array();
    foreach ($myArray as $k=>$subArray) {
       foreach ($subArr as $id=>$value) {
            if($subArray && $value && ($subArray['date'] == $value['date'] && $subArray['customer'] == $value['customer'])){
                $subArr[$id]['total'] += $subArray['total'];
                $subArr[$id]['cg'] += $subArray['cg'];
                unset($myArray[$k]);
            }
        }
     }
     return array_merge($myArray, $subArr);
}

print_r(merge_arr($myArray, $subArr));
//代码结束

//求最优处理上述数组的方法 我这个只能处理2组数组 
//如果2组以上呢?我只能拿2组合并后的结果 再去处理第3个数组 有没优化方法

$mArray = merge_arr($myArray,$subArr);//前2组合并
$threeArray = merge_arr($mArray, $threeArr);
阅读 3.1k
3 个回答

不知道这个能不能满足你

$arrs = array_merge($a,$b,$c);
$narr = array();
array_walk($arrs,function($v)use(&$narr){
    $sha1 = sha1($v['date'].$v['customer']);
    $narr[$sha1]['date']        = $v['date'];
    $narr[$sha1]['customer']    = $v['customer'];
    $narr[$sha1]['total']       = empty($narr[$sha1]['total'])?$v['total']:$narr[$sha1]['total']+$v['total'];
    $narr[$sha1]['cg']          = empty($narr[$sha1]['cg'])?$v['cg']:$narr[$sha1]['cg']+$v['cg'];
});
sort($narr);

数据图
clipboard.png

运行效果图
clipboard.png

基于你代码的方案

  • 首先,将你的代码merge_arr改成merge_arr_two或者其他名字(主要是为了表名,是合并两个数组的)

  • 然后,再写个方法:

function merge_arr() {
    $arrays = func_get_args(); # 这样取出来的是所有参数按照顺序的数组
    $result = [];

    for($i = 0; $i < count($arrays) - 1; $i++) {
        $result = merge_arr_two($arrays[$i], $arrays[$i + 1]);
    }
    
    return $result;
}
  • 调用时候,直接写

merge_arr($arr1, $arr2, $arr3, ...); # 后面可以写很多个

基于你代码的方案2

  • 和上面思路类似,但是,用PHP自带函数array_reduce(),处理参数数组循环

  • array_reduce()作用就是将数组里所有值归总成一个值

  • 代码如下:

function merge_arr() {
    $arrays = func_get_args(); # 这样取出来的是所有参数按照顺序的数组
    $result = array_reduce($arrays, function($arr1, $arr2) {
        return merge_arr_two($arr1, $arr2)
    }, []);
}

新方案:

  • 这个方案,就是以datecustom拼接的字符串,为键名,创建新数组

  • 代码如下:

function merge_arr() {
    $result = [];
    $arrays = func_get_args();
    
    foreach($arrays as $arr) {
        $key = "{$arr['date']}@{$arr['custom']}";
        # 这个是字符串拼接,将一条数据中的date和custom拼成一个字符串,
        # 比如2017-06-14@1163,相同的date和custom组合,就是相同的键名
        # 中间的@符号只是为了将date和custom隔开而已
        
        # 如果对应的值还没被初始化的话,进行初始化
        # 否则后面直接进行相加会出错        
        if(empty($result[$key])) {
            $result[$key] = [];
            $result[$key]['date']   = $arr['date'];
            $result[$key]['custom'] = $arr['custom'];
            $result[$key]['total']  = 0;
            $result[$key]['cg']     = 0;
        }

        $result[$key]['total'] += $arr['total'];
        $result[$key]['cg']    += $arr['cg'];
    }
    
    return array_values($result);
    # 由于之前的数组带有键名,而实际只需要值就行了,用array_values取值
}

处理前的数组
图片描述

处理后的数组
图片描述

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题