php 将多个数组中的列数据按一个数组分组,并对每组的值求和

cygmwpex  于 2023-03-16  发布在  PHP
关注(0)|答案(4)|浏览(157)

我有这样一个数组:

$statuses = ['PROSPECT', 'BACKLOG', 'PROSPECT'];
$of_tranxs = [2, 1, 2];
$revs = [3, 1, 3];
$mgps = [4, 1, 4];

我想通过重复状态求和。输出一个数组如下:

array(
  'status' => ['PROSPECT', 'BACKLOG'],
  'of_tranx' => [4, 1],
  'rev' => [6, 1],
  'mgp' => [8, 1]
)

我使用的是PHP 7.4
我尝试了以下方法:

$result = array_zip_combine(
    ['status', 'of_tranx', 'rev', 'mgp'], 
    $statuses, $of_tranxs, $revs, $mgps
);

然后我预测,但结果不是我想要的。

dgtucam1

dgtucam11#

你可以在原始数组中执行求和,然后在执行一个循环后重新索引并合并它们。我希望这是相当有效的,我认为这将是很容易阅读和维护。
代码:(Demo

foreach ($statuses as $index => $status) {
    if (!isset($found[$status])) {
        $found[$status] = $index;
        continue;
    }
    $of_tranxs[$found[$status]] += $of_tranxs[$index];
    $revs[$found[$status]] += $revs[$index];
    $mgps[$found[$status]] += $mgps[$index];
    unset($statuses[$index], $of_tranxs[$index], $revs[$index], $mgps[$index]);
}
var_export([
    'status' => array_values($statuses),
    'of_tranx' => array_values($of_tranxs),
    'rev' => array_values($revs),
    'mgp' => array_values($mgps)
]);

或者通过维护一个新的索引递增变量来简化:(Demo

$result = [];
$i = 0;
foreach ($statuses as $oldIndex => $status) {
    if (!isset($newIndex[$status])) {
        $newIndex[$status] = $i++;
        $result['status'][] = $status;
        $result['of_tranx'][] = $of_tranxs[$oldIndex];
        $result['rev'][] = $revs[$oldIndex];
        $result['mgp'][] = $mgps[$oldIndex];
    } else {
        $result['of_tranx'][$newIndex[$status]] += $of_tranxs[$oldIndex];
        $result['rev'][$newIndex[$status]] += $revs[$oldIndex];
        $result['mgp'][$newIndex[$status]] += $mgps[$oldIndex];
    }
}
var_export($result);

最后,如果你不想跟踪结果数组中的索引,并且你不想用array_values() x4执行另外的四个循环,那么你可以把引用变量推送到结果数组中。
代码:(Demo

$result = [];
foreach ($statuses as $i => $status) {
    if (!isset($ref[$status])) {
        $ref[$status] = [
            'status' => $status,
            'of_tranxs' => $of_tranxs[$i],
            'revs' => $revs[$i],
            'mgp' => $mgps[$i],
        ];
        $result[] = &$ref[$status];
    } else {
        $ref[$status]['of_tranxs'] += $of_tranxs[$i];
        $ref[$status]['revs'] += $revs[$i];
        $ref[$status]['mgp'] += $mgps[$i];
    }
}
var_export($result);
kxe2p93d

kxe2p93d2#

$array = array(
    'status' => ['PROSPECT','BACKLOG','PROSPECT'],
    'of_tranx' => [2,1,2],
    'rev' => [3,1,3],
    'mgp' => [4,1,4]
);

function sumDuplicatesInArray($array) {
    $dict = [];
    foreach($array as $item) {
        $dict[$item] = is_numeric($item) ? ($dict[$item] ?? 0) + $item : $item;
    }
    return array_values($dict);
}
$final_array = [];
$final_array['status'][]  = sumDuplicatesInArray($array['status']); 
$final_array['of_tranx'][]  = sumDuplicatesInArray($array['of_tranx']); 
$final_array['rev'][]  = sumDuplicatesInArray($array['rev']); 
$final_array['mgp'][]  = sumDuplicatesInArray($array['mgp']); 
print_R($final_array);
tvz2xvvm

tvz2xvvm3#

假设您要获取status的唯一值,然后在其他数组中添加相应的项...
它首先获取状态的唯一值,然后(为了方便起见)将所有其他数组添加到单个数组中以允许foreach
然后遍历原始状态,将值添加到一个新数组(使用array_fill_keys()创建),该数组用于将该类型的所有值加在一起。

$statuses = ['PROSPECT', 'BACKLOG', 'PROSPECT'];
$of_tranxs = [2, 1, 2];
$revs = [3, 1, 3];
$mgps = [4, 1, 4];

$statusUnique = array_unique($statuses);
$arrays = [$of_tranxs, $revs, $mgps];
foreach ($arrays as $index => $array) {
    $out = array_fill_keys($statusUnique, 0);
    foreach ($statuses as $ind => $stat) {
        $out[$stat] += $array[$ind];
    }
    $arrays[$index] = array_values($out);
}
print_r(array_values($statusUnique));
print_r($arrays);

给予...

Array
(
    [0] => PROSPECT
    [1] => BACKLOG
)
Array
(
    [0] => Array
        (
            [0] => 4
            [1] => 1
        )

    [1] => Array
        (
            [0] => 6
            [1] => 1
        )

    [2] => Array
        (
            [0] => 8
            [1] => 1
        )

)
zhte4eai

zhte4eai4#

这个解决方案将允许你提交任意数量的数组,它们不需要只有OP指定的四个。
状态位置引用了其他数组,因此对于状态中的每个副本,我们也需要考虑其他数组的相应位置。
我假设您将始终具有相同的星座,其中具有数值的数组将始终具有与$status数组相同的长度。
那么我相信做一个函数来处理这些是公平的。

<?php
$statuses = ['PROSPECT','BACKLOG','PROSPECT'];
$of_tranxs = [2,1,2];
$revs = [3,1,3];
$mgps = [4,1,4];

function sumDuplicates($statuses, $arrays) {

    $dict = [];
    foreach($statuses as $i => $status) {
        foreach ($arrays as $key => $array) {
            if(!isset($dict['status'][$status])) $dict['status'][$status] = $i;
            $dict[$key][$dict['status'][$status]] = ($dict[$key][$dict['status'][$status]] ?? 0) + $array[$i];
        }
    }
    
    $dict['status'] = array_flip($dict['status']);
    foreach($dict as $i => $array) {
        $dict[$i] = array_values($array);
    }
    return $dict;
}

print_r(sumDuplicates($statuses, ["of_tranx" => $of_tranxs, "rev" => $revs, "mgp" => $mgps]));

预期输出应为

Array
(
    [status] => Array
        (
            [0] => PROSPECT
            [1] => BACKLOG
        )

    [of_tranx] => Array
        (
            [0] => 4
            [1] => 1
        )

    [rev] => Array
        (
            [0] => 6
            [1] => 1
        )

    [mgp] => Array
        (
            [0] => 8
            [1] => 1
        )

)

如果你只需要一个或多个数组求和,只需编辑函数调用。你可以这样做:

sumDuplicates($statuses, ["of_tranx" => $of_tranxs])

这只会输出of_trax的和。

相关问题