
在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函数来实现上述数据合并:
<?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>";
?>这种方法简洁明了,利用了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>";
?>本教程详细介绍了如何在PHP中将一个数组中基于共同标识符的重复属性聚合到另一个目标数组中。我们提供了两种实现方案:
选择哪种方案取决于您的具体应用场景和数据规模。理解这些数组操作技巧,将有助于您更高效、更灵活地处理PHP中的数据整合任务。
以上就是PHP数组深度合并:按ID聚合多重属性的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号