如何使用键合并子数组并将值相加?

时间:2018-01-20 12:46:00

标签: php multidimensional-array merge sum

我对PHP很新,我在使用数组和组合数据方面遇到了一些麻烦。我有一个从foreach循环创建的以下数组:

array(1) {
    [36868]=> int(3)
}
array(1) {
    [2112]=> int(3)
} 
array(1) { 
    [35901]=> int(3) 
} 
array(1) { 
    [6496]=> int(3) 
} 
array(1) { 
    [87]=> int(3) 
} 
array(1) { 
    [36868]=> int(3) 
} 
array(1) { 
    [68]=> int(3) 
} 
array(1) { 
    [9068]=> int(3) 
} 
array(1) { 
    [47]=> int(3) 
}

每个数组中的键都是一个用户ID,所以我需要保留它,但我只需要每个键的一个实例,并且有重复的键,将值相加。像这样:

array(1) {
    [36868]=> int(6)
}
array(1) {
    [2112]=> int(3)
} 
array(1) { 
    [35901]=> int(3) 
} 
array(1) { 
    [6496]=> int(3) 
} 
array(1) { 
    [87]=> int(3) 
} 
array(1) { 
    [68]=> int(3) 
} 
array(1) { 
    [9068]=> int(3) 
} 
array(1) { 
    [47]=> int(3) 
}

我试过在数组中循环:

foreach ($array as $key => &$value) {
    if ($value[0] == $value[1]) {
        $value[1] += $value[1];
    }
}

但没有运气。我也试过以不同的方式渲染数组,[userid]=>1,[score]=>3,我觉得我会绕圈子走一圈,所以任何帮助都会非常感激。

2 个答案:

答案 0 :(得分:2)

$data <-- this is your original array

$result = array_reduce(
    $data,
    function($carry, $item) {
        foreach ($item as $id => $score) {
            if (array_key_exists($id, $carry)) {
                $carry[$id] += $score;
            } else {
                $carry[$id] = $score;
            }
        }

        return $carry;
    },
    []
);

如果您确定每个项目只包含1个条目,您还可以简化回调以不使用foreach:

$result = array_reduce(
    $data,
    function ($carry, $item) {
        $score = reset($item); 
        $id = key($item);

        if (array_key_exists($id, $carry)) {
            $carry[$id] += $score;
        } else {
            $carry[$id] = $score;
        }

        return $carry;
    },
    []
);

你也可以继续使用foreach:

/** foreach to create a $data array like described below and afterwards do this: **/
$result = [];
foreach($data as $row) {
    $score = reset($row);
    $id = key($row);

    if (array_key_exists($id, $result)) {
        $result[$id] += $score;
    } else {
        $result[$id] = $score;
    }
}

这将采用如下数组$data

array(
    array('1' => 3),
    array('1' => 3),
    array('2' => 3),
);

并创建变量$result,如下所示:

array(
    '1' => 6,
    '2' => 3,
);

答案 1 :(得分:0)

这是一个不会产生通知的干净方法。合并求和数组数据时,有效的方法是生成临时密钥并使用非常快的isset()函数。我可以使用current()key()来访问单独的子数组元素,但第二个foreach控制结构实际上更快,更紧凑。 (参考: https://stackoverflow.com/a/21219594/2943403

代码:(演示:https://3v4l.org/QkB09

$array=[
    [36868=>3],
    [2112=>3],
    [35901=>3],
    [6496=>3],
    [87=>3],
    [36868=>3],
    [68=>3],
    [9068=>3],
    [47=>3]
];
foreach($array as $subarray){
    foreach($subarray as $k=>$v){
        if(!isset($result[$k])){
            $result[$k]=$subarray;
        }else{
            $result[$k][$k]+=$v;
        }
    }
}
var_export(array_values($result));

输出:

array (
  0 => 
  array (
    36868 => 6,
  ),
  1 => 
  array (
    2112 => 3,
  ),
  2 => 
  array (
    35901 => 3,
  ),
  3 => 
  array (
    6496 => 3,
  ),
  4 => 
  array (
    87 => 3,
  ),
  5 => 
  array (
    68 => 3,
  ),
  6 => 
  array (
    9068 => 3,
  ),
  7 => 
  array (
    47 => 3,
  ),
)