假设我有以下数组:
$first = [
['id' => 5, 'name' => 'Education'],
['id' => 4, 'name' => 'Computers'],
['id' => 7, 'name' => 'Science'],
['id' => 1, 'name' => 'Sports'],
];
$second = [
['id' => 1, 'title' => 'Sport'],
['id' => 7, 'title' => 'Sci'],
['id' => 4, 'title' => 'Comp'],
['id' => 5, 'title' => 'Edu'],
];
期望的输出是:
[
['id' => 5, 'name' => 'Education', 'title' => 'Edu'],
['id' => 4, 'name' => 'Computers', 'title' => 'Comp'],
['id' => 7, 'name' => 'Science', 'title' => 'Sci'],
['id' => 1, 'name' => 'Sports', 'title' => 'Sport'],
]
我已经成功地简单地合并了这些数组:
foreach ($first as $key => $value) {
$result[$key] = array_merge($first[$key], $second[$key]);
}
但是输出是由第一级索引而不是它们的
id
值组合的:
Array
(
[0] => Array
(
[id] => 5
[name] => Education
[title] => Sport
)
[1] => Array
(
[id] => 4
[name] => Computers
[title] => Sci
)
[3] => Array
(
[id] => 7
[name] => Science
[title] => Comp
[4] => Array
(
[id] => 1
[name] => Sports
[title] => Edu
)
)
我想将第二个数组中的标题值附加到第一个数组,其中存在匹配的
id
值并保持第一个数组的排序。
我怎样才能实现这个目标?
您可以执行嵌套循环并检查
id
值是否匹配,然后将 title
添加到 $first
(或将 name
添加到 $second
)
foreach($first as $key => $value){
foreach($second as $value2){
if($value['id'] === $value2['id']){
$first[$key]['title'] = $value2['title'];
}
}
}
您的代码运行良好。你的期望根本就是不正确的。例如,在一个数组中,第 4 个元素
id
为 1,但在另一个数组中,第 4 个元素 id
为 5,因此您的 “将这些数组合并到同一个 id 上” 没有任何意义,因为将第 4 个元素合并到您也可以合并它们的子项,并且由于两个数组中都使用了id
,因此一旦值必须消失,因为数组中不能有两个相等的键。
编辑
您必须手动合并,因为 PHP 函数基于 keys 合并,而您想基于 content 合并:
$result = array();
foreach( $arrayA as $keyA => $valA ) {
foreach( $arrayB as $keyB => $valB ) {
if( $valA['id'] == $valB['id'] ) {
$result[$keyA] = $valA + $valB;
// or if you do not care output keys, just
// $result[] = $valA + $valB;
}
}
}
提供
PHP 5.5+
中可用的替代方法。
由于两个数组的顺序不相同,因此首先使用 array_column 通过
id
对数组进行索引。
这将允许您在 id
索引数组上使用
array_replace_recusrive。
array_replace_recursive
将合并与两个数组集的索引关联匹配的数组中的值。
可以选择使用
array_values
重新索引数组,删除 id
索引关联。
$first = array_column($first, null, 'id');
$second = array_column($second, null, 'id');
$result = array_values(array_replace_recursive($first, $second));
结果
Array
(
[0] => Array
(
[id] => 5
[name] => Education
[title] => Edu
)
[1] => Array
(
[id] => 4
[name] => Computers
[title] => Comp
)
[2] => Array
(
[id] => 7
[name] => Science
[title] => Sci
)
[3] => Array
(
[id] => 1
[name] => Sports
[title] => Sport
)
)
不要在foreach中使用foreach,当数组很大时,可能会太慢。
$idArray = array_column($secondArray,'title','id');
foreach($firstArray as $key => $val){
$firstArray[$key]['title'] = (isset($idArray[$val['id']])) ? $idArray[$val['id']] : 'some title';
}
array_column
的 3 参数形式,通过 second
值重新索引 id
数组,然后循环 first
数组,合并匹配 的内容second
值(如果存在):
$second = array_column($second, null, 'id');
foreach ($first as &$subject) {
$subject = array_merge($subject, $second[$subject['id']] ?? []);
}
输出:
Array
(
[0] => Array
(
[id] => 5
[name] => Education
[title] => Edu
)
[1] => Array
(
[id] => 4
[name] => Computers
[title] => Comp
)
[3] => Array
(
[id] => 7
[name] => Science
[title] => Sci
)
[4] => Array
(
[id] => 1
[name] => Sports
[title] => Sport
)
)
这比 Will B. 的答案(不重新索引
first
数组)有优势。由于只有一次对 array_column
的调用,并且没有对 array_values
的调用,它的速度也稍快一些(我的测试显示 ~10%)。
更新
实际上可以通过使用 数组联合运算符(
+
)(感谢@mickmackusa)来加快这段代码的速度:
$second = array_column($second, null, 'id');
foreach ($first as &$subject) {
$subject += $second[$subject['id']] ?? [];
}
这段代码的输出与上面相同,但运行速度又快了 10% 左右。
确保项目的顺序相同:
$items = array_map(function($itemFirstArray, $itemSecondArray) {
return array_merge($itemFirstArray, $itemSecondArray);
}, $firstArray, $secondArray);
按“id”字段对两个数组进行排序,然后让 php 与 array_replace_recursive 进行合并。
function cmp($a, $b) {
return ((int) $a['id'] < (int) $b['id']) ? -1 : 1;
}
usort($array1, 'cmp');
usort($array2, 'cmp');
$result = array_replace_recursive($array1, $array2);