
在数据处理中,我们经常会遇到需要对结构化数据进行聚合的场景。例如,给定一组并行数组,其中一个数组作为分组依据(如状态),而其他数组包含需要聚合(如求和)的数值。本教程将探讨几种在php中实现这一目标的高效方法。
假设我们有以下几组并行数组,它们在索引上是一一对应的:
$statuses = ['PROSPECT', 'BACKLOG', 'PROSPECT']; $of_tranxs = [2, 1, 2]; $revs = [3, 1, 3]; $mgps = [4, 1, 4];
我们的目标是根据 $statuses 数组中的值进行分组,并对 of_tranxs、revs 和 mgps 数组中对应的值进行求和。最终输出应是一个结构化的数组,例如:
array( 'status' => ['PROSPECT', 'BACKLOG'], 'of_tranx' => [4, 1], 'rev' => [6, 1], 'mgp' => [8, 1] )
下面将介绍三种不同的实现策略。
这种方法通过在原始数组上进行操作来聚合数据。它利用一个辅助数组来记录每个分组键首次出现时的索引,后续遇到重复键时,将对应的值累加到首次出现的索引位置,并删除重复项。最后,对所有数组进行重新索引以获得紧凑的结果。
立即学习“PHP免费学习笔记(深入)”;
<?php
$statuses = ['PROSPECT', 'BACKLOG', 'PROSPECT'];
$of_tranxs = [2, 1, 2];
$revs = [3, 1, 3];
$mgps = [4, 1, 4];
$found = []; // 用于记录每个状态首次出现的索引
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]);
}
// 重新索引所有数组,确保键的连续性
$result = [
'status' => array_values($statuses),
'of_tranx' => array_values($of_tranxs),
'rev' => array_values($revs),
'mgp' => array_values($mgps)
];
var_export($result);
?>此方法通过构建一个新的结果数组来避免对原始数据的修改。它维护一个映射关系,将每个状态映射到新结果数组中的一个递增索引,从而实现数据的聚合。
<?php
$statuses = ['PROSPECT', 'BACKLOG', 'PROSPECT'];
$of_tranxs = [2, 1, 2];
$revs = [3, 1, 3];
$mgps = [4, 1, 4];
$result = [];
$newIndex = []; // 映射:状态 -> 新数组中的索引
$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 {
// 状态已存在,累加到对应位置
$targetNewIndex = $newIndex[$status];
$result['of_tranx'][$targetNewIndex] += $of_tranxs[$oldIndex];
$result['rev'][$targetNewIndex] += $revs[$oldIndex];
$result['mgp'][$targetNewIndex] += $mgps[$oldIndex];
}
}
var_export($result);
?>这种方法结合了构建新数组的优点,并利用PHP的引用机制,避免了手动管理索引的复杂性,同时减少了 array_values() 的调用。它通过一个临时引用数组来直接操作最终结果数组中的元素。
<?php
$statuses = ['PROSPECT', 'BACKLOG', 'PROSPECT'];
$of_tranxs = [2, 1, 2];
$revs = [3, 1, 3];
$mgps = [4, 1, 4];
$result = [];
$ref = []; // 映射:状态 -> 结果数组中对应元素的引用
foreach ($statuses as $i => $status) {
if (!isset($ref[$status])) {
// 首次遇到该状态,创建新的数据结构并将其引用存入 $ref
$ref[$status] = [
'status' => $status,
'of_tranx' => $of_tranxs[$i],
'rev' => $revs[$i],
'mgp' => $mgps[$i],
];
// 将引用推入 $result,后续对 $ref[$status] 的修改会直接影响 $result
$result[] = &$ref[$status];
} else {
// 状态已存在,通过引用直接累加值
$ref[$status]['of_tranx'] += $of_tranxs[$i];
$ref[$status]['rev'] += $revs[$i];
$ref[$status]['mgp'] += $mgps[$i];
}
}
var_export($result);
?>本文介绍了三种在PHP中根据一个数组分组并聚合其他并行数组数值的方法:原地修改与重新索引、构建新数组并维护索引,以及利用引用高效构建结果集。每种方法都有其独特的优点和适用场景。在实际开发中,开发者应根据项目需求、性能考量和代码可读性偏好来选择最合适的实现策略。通常情况下,方法三(利用引用)在提供清晰输出结构的同时,兼顾了效率和代码简洁性,是一个非常推荐的解决方案。
以上就是PHP中多维数组按键分组并聚合数值的技巧的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号