计算平面数组中每个唯一值的映射值之和

问题描述 投票:0回答:6

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

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

如何从

$array1
中获取该数字对应键的每个唯一数字
1,2,3
(意思是
$array2
)的总和。

示例;对于

1
的值
$array1
,我们得到了键
0, 1, 2
。现在我想对
$array2
中具有这些键的值求和,得到
2 + 4 + 5 = 11

我是否会编写一个循环来获取

1
中具有
$array1
的所有索引,然后使用这些索引获取
$array2
中的所有值,依此类推?

php arrays sum mapping grouping
6个回答
3
投票

您可以使用

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
元素。

请注意,我们使用

$total
初始化
array_fill_keys
只是为了避免在创建新
$total
元素时发出通知。


2
投票

说明

首先,我们只需用

$array1
 翻转它即可从 
array_flip()
获得所有唯一值。由于不能有重复的键,因此我们最终将所有唯一值作为
$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
)

2
投票

如果您已经将值推入

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

0
投票

尝试使用函数式方法

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)
}

0
投票

使用

1 , 1 , 1 , 2 , 2 , 3
array_count_values
array_walk
函数解决有序序列(如
array_sum
):

$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.php
http://php.net/manual/en/function.array-walk.php


0
投票

此处所示,循环映射数组,然后在遇到重复的标识值时进行分组和求和。

代码:(演示

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

$result = [];
foreach ($array1 as $index => $id) {
    $result[$id] = ($result[$id] ?? 0) + $array2[$index];
}
var_export($result);
© www.soinside.com 2019 - 2024. All rights reserved.