0

0

PHP中多维数组按键分组并聚合数值的技巧

聖光之護

聖光之護

发布时间:2025-10-05 10:06:01

|

469人浏览过

|

来源于php中文网

原创

PHP中多维数组按键分组并聚合数值的技巧

本文详细介绍了在PHP中如何将多个并行数组根据其中一个数组的键进行分组,并对其他关联数组中的数值进行求和。文章提供了三种不同的实现策略,包括原地修改与重新索引、构建新数组并维护索引,以及利用引用高效构建结果集,旨在帮助开发者选择最适合其场景的解决方案。

在数据处理中,我们经常会遇到需要对结构化数据进行聚合的场景。例如,给定一组并行数组,其中一个数组作为分组依据(如状态),而其他数组包含需要聚合(如求和)的数值。本教程将探讨几种在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免费学习笔记(深入)”;

Cutout.Pro抠图
Cutout.Pro抠图

AI批量抠图去背景

下载

实现步骤

  1. 遍历作为分组依据的 $statuses 数组。
  2. 使用一个 $found 数组记录每个状态首次出现的原始索引。
  3. 如果当前状态是首次出现,则将其原始索引存入 $found。
  4. 如果当前状态已存在于 $found 中,则将当前索引对应的 of_tranxs、revs 和 mgps 值累加到 $found 中记录的首次出现索引的位置。
  5. 累加完成后,删除当前索引在所有原始数组中的对应元素。
  6. 循环结束后,使用 array_values() 函数对所有数组进行重新索引,移除空缺的键,得到最终结果。

示例代码

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

优点与缺点

  • 优点: 内存效率相对较高,因为它直接修改原始数组。
  • 缺点: 破坏性操作,会修改原始数组。代码可读性略低于构建新数组的方法,且最后需要多次调用 array_values()。

方法二:构建新数组并维护索引

此方法通过构建一个新的结果数组来避免对原始数据的修改。它维护一个映射关系,将每个状态映射到新结果数组中的一个递增索引,从而实现数据的聚合。

实现步骤

  1. 初始化一个空的 $result 数组和一个递增的 $i 变量作为新数组的索引。
  2. 初始化一个 $newIndex 数组,用于存储每个状态在新结果数组中的对应索引。
  3. 遍历 $statuses 数组。
  4. 如果当前状态在 $newIndex 中不存在:
    • 将当前状态添加到 $result['status']。
    • 将当前索引对应的 of_tranxs、revs、mgps 值添加到 $result 对应的子数组中。
    • 将当前状态与 $i 进行映射,并将 $i 递增。
  5. 如果当前状态已存在于 $newIndex 中:
    • 获取其在新数组中的索引 $newIndex[$status]。
    • 将当前索引对应的 of_tranxs、revs、mgps 值累加到 $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 {
        // 状态已存在,累加到对应位置
        $targetNewIndex = $newIndex[$status];
        $result['of_tranx'][$targetNewIndex] += $of_tranxs[$oldIndex];
        $result['rev'][$targetNewIndex] += $revs[$oldIndex];
        $result['mgp'][$targetNewIndex] += $mgps[$oldIndex];
    }
}

var_export($result);
?>

优点与缺点

  • 优点: 非破坏性操作,原始数组保持不变。代码逻辑清晰,易于理解和维护。
  • 缺点: 需要额外的内存来存储 $result 和 $newIndex 数组。

方法三:利用引用高效构建结果集

这种方法结合了构建新数组的优点,并利用PHP的引用机制,避免了手动管理索引的复杂性,同时减少了 array_values() 的调用。它通过一个临时引用数组来直接操作最终结果数组中的元素。

实现步骤

  1. 初始化一个空的 $result 数组。
  2. 初始化一个 $ref 数组,用于存储每个状态的引用。
  3. 遍历 $statuses 数组。
  4. 如果当前状态在 $ref 中不存在:
    • 创建一个包含当前状态及对应数值的关联数组。
    • 将此关联数组的引用存储到 $ref[$status] 中。
    • 将这个引用推入 $result 数组。这样,对 $ref[$status] 的任何修改都会直接反映到 $result 中。
  5. 如果当前状态已存在于 $ref 中:
    • 通过 $ref[$status] 引用,直接累加对应数值。

示例代码

 结果数组中对应元素的引用

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);
?>

优点与缺点

  • 优点: 非破坏性操作,原始数组保持不变。代码简洁,无需显式管理新数组的索引。避免了 array_values() 的多次调用。结果数组的每个元素都是一个包含所有相关字段的关联数组,结构更清晰。
  • 缺点: 使用引用可能会增加初学者的理解难度。

注意事项

  • 性能考量: 对于小型数据集,这三种方法的性能差异不大。但对于大型数据集,方法一(原地修改)可能在内存使用上略有优势,因为它避免了创建大量新数组元素。方法三(使用引用)在代码简洁性和避免重复 array_values() 调用方面表现良好,通常是推荐的选择。
  • 代码可读性与维护性: 方法二和方法三通常被认为具有更好的可读性,因为它们不修改原始数据。方法三的输出格式(每个元素都是一个关联数组)在某些场景下可能更易于后续处理。
  • 数据结构: 本教程中,所有数组都是并行且索引一一对应的。如果数据结构更复杂(例如,多维关联数组),则需要调整遍历和聚合逻辑。
  • PHP版本: 示例代码在PHP 7.4及更高版本中均可正常运行。

总结

本文介绍了三种在PHP中根据一个数组分组并聚合其他并行数组数值的方法:原地修改与重新索引、构建新数组并维护索引,以及利用引用高效构建结果集。每种方法都有其独特的优点和适用场景。在实际开发中,开发者应根据项目需求、性能考量和代码可读性偏好来选择最合适的实现策略。通常情况下,方法三(利用引用)在提供清晰输出结构的同时,兼顾了效率和代码简洁性,是一个非常推荐的解决方案。

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

1974

2023.09.01

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

1295

2023.10.11

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

1203

2023.10.11

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

948

2023.10.23

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

1400

2023.10.23

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

1229

2023.11.03

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1439

2023.11.09

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1303

2023.11.13

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 8.1万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 6.9万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号