0

0

PHP数组深度合并:按ID聚合多重属性

花韻仙語

花韻仙語

发布时间:2025-10-01 13:56:01

|

847人浏览过

|

来源于php中文网

原创

PHP数组深度合并:按ID聚合多重属性

本教程将指导您如何在PHP中高效地合并两个数组。我们将探讨一种场景,其中一个数组包含基于共同标识符(如epid)的重复记录,而另一个数组是目标结构。目标是将第一个数组中所有匹配标识符的特定字段(如hash)聚合到一个子数组中,并添加到第二个数组的相应记录中,从而实现数据的深度整合。

引言:PHP数组数据整合的挑战

php开发中,我们经常需要处理来自不同源或具有不同结构的数据集,并将其整合以满足特定的业务需求。一个常见的挑战是,当一个数组包含基于某个共同标识符的重复记录,而另一个数组是我们的目标结构时,如何将第一个数组中所有匹配标识符的特定属性聚合起来,并添加到目标数组的相应记录中。

例如,假设我们有两个数组:

数组1 (源数据): 包含产品ID (epid) 和哈希值 (hash)。同一个epid可能出现多次,每个都有一个hash值。

[
  ["epid" => "123", "hash" => "xxxxxxA"],
  ["epid" => "456", "hash" => "xxxxxxB"],
  ["epid" => "789", "hash" => "xxxxxxC"],
  ["epid" => "123", "hash" => "xxxxxxD"],
  ["epid" => "123", "hash" => "xxxxxxE"],
]

数组2 (目标数据): 包含产品ID (epid) 和名称 (name)。每个epid在这里是唯一的。

[
  ["epid" => "123", "name" => "This is a title"],
  ["epid" => "456", "name" => "This is a title"],
  ["epid" => "789", "name" => "This is a title"]
]

我们的目标是将数组1中所有与数组2中epid匹配的hash值收集起来,形成一个hash数组,并添加到数组2的相应记录中。最终结果应如下所示:

立即学习PHP免费学习笔记(深入)”;

[
  ["epid" => "123", "name" => "This is a title", "hash" => [ "xxxxxxA", "xxxxxxD", "xxxxxxE" ] ],
  ["epid" => "456", "name" => "This is a title", "hash" => [ "xxxxxxB" ] ],
  ["epid" => "789", "name" => "This is a title", "hash" => [ "xxxxxxC" ] ]
]

核心解决方案:遍历与聚合

解决此类问题的核心思路是遍历目标数组,对其中的每个元素,在源数组中查找所有匹配的记录,并提取所需的属性进行聚合。PHP提供了一些内置函数,可以帮助我们高效地完成这一任务。

示例代码

以下代码展示了如何使用array_column和array_keys函数来实现上述数据合并:

Imagine By Magic Studio
Imagine By Magic Studio

AI图片生成器,用文字制作图片

下载
<?php
// 原始数据:数组1 (lookup) 和 数组2 (db)
$lookup = [
    ["epid" => "123", "hash" => "xxxxxxA"],
    ["epid" => "456", "hash" => "xxxxxxB"],
    ["epid" => "789", "hash" => "xxxxxxC"],
    ["epid" => "123", "hash" => "xxxxxxD"],
    ["epid" => "123", "hash" => "xxxxxxE"],
];

$db = [
    ["epid" => "123", "name" => "This is a title"],
    ["epid" => "456", "name" => "This is a title"],
    ["epid" => "789", "name" => "This is a title"]
];

// 遍历目标数组 $db
foreach($db as $i => $el) {
    // 步骤1: 使用 array_column 提取 $lookup 数组中所有 'epid' 列的值
    // 步骤2: 使用 array_keys 查找哪些键的 'epid' 值与当前 $el["epid"] 匹配
    $matchingKeys = array_keys(array_column($lookup, 'epid'), $el["epid"]);

    // 遍历所有匹配的键,将对应的 'hash' 值添加到 $db 数组的当前元素中
    foreach($matchingKeys as $key) {
        // 如果 $db[$i]["hash"] 键不存在,它会在第一次赋值时自动创建为一个数组
        $db[$i]["hash"][] = $lookup[$key]["hash"];
    }
}

// 输出合并后的结果
echo "<pre>";
var_dump($db);
echo "</pre>";
?>

代码解析

  1. 初始化数组: $lookup 变量存储了源数据(数组1),$db 变量存储了目标数据(数组2)。
  2. 外层循环: foreach($db as $i => $el) 遍历 $db 数组的每个元素。$i 是当前元素的索引,$el 是当前元素的值(一个关联数组)。
  3. 查找匹配键:
    • array_column($lookup, 'epid'):这个函数会从 $lookup 数组中抽取所有子数组的 'epid' 键对应的值,并返回一个新的一维数组。例如,它会生成 ["123", "456", "789", "123", "123"]。
    • array_keys(..., $el["epid"]):这个函数会在上一步生成的一维数组中查找所有值为 $el["epid"] 的元素的键。这些键实际上对应着 $lookup 数组中匹配元素的原始索引。例如,当 $el["epid"] 是 "123" 时,$matchingKeys 将会是 [0, 3, 4]。
  4. 内层循环聚合: foreach($matchingKeys as $key) 遍历所有找到的匹配键。
    • $db[$i]["hash"][] = $lookup[$key]["hash"];:这行代码是实现聚合的关键。它通过 $key 访问 $lookup 数组中对应的元素,提取其 'hash' 值,并将其添加到 $db 数组当前元素 ($db[$i]) 的 'hash' 键下。
      • 如果 $db[$i] 中还没有 'hash' 键,PHP 会在第一次执行此操作时自动将其创建为一个空数组,然后将值添加进去。
      • [] 语法确保每次添加都是作为新元素追加到数组的末尾。

这种方法简洁明了,利用了PHP内置函数的高效性,避免了手动编写复杂的嵌套循环来查找匹配项。

性能优化与注意事项

上述解决方案对于中小型数组是高效且可读的。然而,对于非常大的数组,每次外层循环都调用 array_column 和 array_keys 可能会导致性能瓶颈,因为 array_column 每次都会遍历整个 $lookup 数组。在这种情况下,我们可以通过预处理 $lookup 数组来构建一个查找表,从而显著提高性能。

优化方案:构建查找表

通过一次性遍历 $lookup 数组,我们可以创建一个以 epid 为键,以 hash 数组为值的查找表。这样,在遍历 $db 数组时,我们就可以通过 epid 直接进行 O(1)(平均时间复杂度)的查找。

<?php
// 原始数据:数组1 (lookup) 和 数组2 (db)
$lookup = [
    ["epid" => "123", "hash" => "xxxxxxA"],
    ["epid" => "456", "hash" => "xxxxxxB"],
    ["epid" => "789", "hash" => "xxxxxxC"],
    ["epid" => "123", "hash" => "xxxxxxD"],
    ["epid" => "123", "hash" => "xxxxxxE"],
];

$db = [
    ["epid" => "123", "name" => "This is a title"],
    ["epid" => "456", "name" => "This is a title"],
    ["epid" => "789", "name" => "This is a title"]
];

// 步骤1:预处理 $lookup 数组,构建以 epid 为键的查找表
$hashLookupMap = [];
foreach ($lookup as $item) {
    $epid = $item['epid'];
    $hash = $item['hash'];
    // 如果该 epid 键不存在,则初始化为一个空数组
    if (!isset($hashLookupMap[$epid])) {
        $hashLookupMap[$epid] = [];
    }
    // 将 hash 值添加到对应的 epid 键下的数组中
    $hashLookupMap[$epid][] = $hash;
}

// 步骤2:遍历 $db 数组,利用查找表合并数据
foreach ($db as $i => $el) {
    $epid = $el['epid'];
    // 检查查找表中是否存在当前 epid
    if (isset($hashLookupMap[$epid])) {
        $db[$i]['hash'] = $hashLookupMap[$epid];
    } else {
        // 可选:如果 $db 中的 epid 在 $lookup 中没有匹配项,
        // 可以选择添加一个空数组,或者不添加 'hash' 键
        // $db[$i]['hash'] = [];
    }
}

// 输出合并后的结果
echo "<pre>";
var_dump($db);
echo "</pre>";
?>

其他注意事项

  • 数据类型一致性: 确保用于匹配的键(如 epid)在两个数组中的数据类型是一致的(例如,都是字符串或都是整数),以避免意外的比较结果。
  • 内存使用: 对于包含数百万条记录的超大型数组,即使是优化后的查找表方法也可能消耗大量内存。在这种极端情况下,可能需要考虑分批处理数据,或者利用数据库的连接和聚合功能来完成任务。
  • epid 不存在的情况: 在优化方案中,如果 $db 数组中的某个 epid 在 $hashLookupMap 中没有对应的键,则 $db[$i]['hash'] 将不会被设置。根据业务需求,您可能希望在这种情况下显式地将其设置为一个空数组 [],如代码注释所示。

总结

本教程详细介绍了如何在PHP中将一个数组中基于共同标识符的重复属性聚合到另一个目标数组中。我们提供了两种实现方案:

  1. 基于 array_column 和 array_keys 的方案: 适用于中小型数组,代码简洁,易于理解。
  2. 基于预构建查找表的优化方案: 适用于大型数组,通过一次性预处理源数据,显著提高了查找效率,降低了整体时间复杂度。

选择哪种方案取决于您的具体应用场景和数据规模。理解这些数组操作技巧,将有助于您更高效、更灵活地处理PHP中的数据整合任务。

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

338

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

225

2025.10.31

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

138

2026.02.12

php中foreach用法
php中foreach用法

本专题整合了php中foreach用法的相关介绍,阅读专题下面的文章了解更多详细教程。

267

2025.12.04

mysql标识符无效错误怎么解决
mysql标识符无效错误怎么解决

mysql标识符无效错误的解决办法:1、检查标识符是否被其他表或数据库使用;2、检查标识符是否包含特殊字符;3、使用引号包裹标识符;4、使用反引号包裹标识符;5、检查MySQL的配置文件等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

210

2023.12.04

Python标识符有哪些
Python标识符有哪些

Python标识符有变量标识符、函数标识符、类标识符、模块标识符、下划线开头的标识符、双下划线开头、双下划线结尾的标识符、整型标识符、浮点型标识符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

322

2024.02.23

java标识符合集
java标识符合集

本专题整合了java标识符相关内容,想了解更多详细内容,请阅读下面的文章。

292

2025.06.11

c++标识符介绍
c++标识符介绍

本专题整合了c++标识符相关内容,阅读专题下面的文章了解更多详细内容。

178

2025.08.07

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

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

精品课程

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

共137课时 | 13.4万人学习

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

共6课时 | 11.3万人学习

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

共13课时 | 1.0万人学习

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

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