基于键交集对数组值求和


Sum array values based on key intersection

我有一个循环,我同时将值推入两个数组,所以我得到两个这样的数组:

$array1 = [ 1 , 1 , 1 , 2 , 2 , 3 ];
$array2 = [ 2 , 4 , 5 , 2 , 1 , 5 ];

我如何从$array2中获取每个唯一$array1数的总和,即1,2,3,该数字的相应键。

例如;对于$array1的值1,我们得到了0, 1, 2键。现在我想总结具有这些键的$array2的值,从而产生2 + 4 + 5 = 11 .

我会编写一个循环来获取$array1 1的所有索引,然后从这些索引的$array2中获取所有值,依此类推?

您可以使用

array_map传递来使两个数组运行,并使用对每个总计的空数组的引用:

$total = array_fill_keys( array_unique($array1), 0 );
array_map
(
    function( $a, $b ) use( &$total )
    {
        $total[$a] += $b;
    },
    $array1,
    $array2
);
print_r( $total );

输出:

Array
(
    [1] => 11
    [2] => 3
    [3] => 5
)

eval.in 演示

array_map接受多个数组,并同步传递其每个项目,因此您可以将每个$array2值求和到$total元素$array1键与该值相同。

请注意,我们使用array_fill_keys初始化$total只是为了避免在创建新$total元素时发出通知。

解释

首先,我们只需用 array_flip() 翻转即可从$array1中获取所有唯一值。由于您不能有重复的键,因此我们最终将所有唯一值作为$uniqueValues中的键。我们还使用一个空数组初始化$sum,我们将每个值的总和放入其中。

现在我们遍历所有唯一值并从 $array1 中获取所有键,这些键具有该特定值array_keys()

然后我们从第二个数组中获取所有值,其中包含我们对 array_intersect_key() 执行的键。请注意,由于我们按键进行交集,因此我们必须翻转键数组,以便将键作为数组的键。

之后,我们将$array2中的所有值都放在一个数组中,这对应于当前迭代中第一个数组的值。我们可以将其与array_sum()相加并将其保存在$sum中。

法典

<?php
    $array1 = [ 1 , 1 , 1 , 2 , 2 , 3 ];
    $array2 = [ 2 , 4 , 5 , 2 , 1 , 5 ];
    $sum = [];
    $uniqueValues = array_flip($array1);
    foreach($uniqueValues as $v => $notNeeded){
        $keys = array_keys($array1, $v);
        $sum[$v] = array_sum(array_intersect_key($array2, array_flip($keys)));
    }
    print_r($sum);
?>

输出:

Array (
    [1] => 11
    [2] => 3
    [3] => 5
)

如果您已经将值推送到$array1中,同时对$array2也是如此,为什么不简单地创建第三个数组并使用第一个数组中的键将第二个数组的值推送到相应元素的总和中?!

因此,您不必调用任何其他函数来执行此操作,并且可以在循环本身中执行此操作。

伪代码:

<?php
    $sum = [];
    loop {
        $arrayOne[] = $valueOne;
        $arrayTwo[] = $valueTwo;

        if(!isset($sum[$valueOne]))
            $sum[$valueOne] = 0;
        $sum[$valueOne] += $valueTwo;
    }
    print_r($sum);
?>

因此,您最终会得到一个具有如下模式的数组:

Array (
    [unique value from array one] => sum
)

尝试对array_reduce使用函数式方法:

<?php
$array1 = [ 1 , 1 , 1 , 2 , 2 , 3 ];
$array2 = [ 2 , 4 , 5 , 2 , 1 , 5 ];
$newArray = array_reduce($array1, function($carry, $item) use($array2) {
    $item2 = $array2[$carry['index']];
    $carry[$item] = empty($carry[$item]) ? $item2 : $carry[$item] + $item2;
    $carry['index'] = $carry['index'] + 1;
    return $carry;
}, ['index' => 0]);
unset($newArray['index']);
var_dump($newArray);

输出将是:

array(3) {
  [1]=>
  int(11)
  [2]=>
  int(3)
  [3]=>
  int(5)
}

使用array_count_valuesarray_walkarray_sum函数的有序序列(如1 , 1 , 1 , 2 , 2 , 3(的解决方案:

$array1 = [ 1 , 1 , 1 , 2 , 2 , 3 ];
$array2 = [ 2 , 4 , 5 , 2 , 1 , 5 ];
$counts = array_count_values($array1);
$offset = 0;
$sums = [];
array_walk($counts, function($v, $k) use($counts, &$sums, $array2, &$offset){
    $offset += isset($counts[$k-1])? $counts[$k-1] : 0;
    $sums[$k] = array_sum(array_slice($array2, $offset, $v));
});
print_r($sums);

输出:

Array
(
    [1] => 11
    [2] => 3
    [3] => 5
)


http://php.net/manual/en/function.array-count-values.phphttp://php.net/manual/en/function.array-walk.php