我有以下3个多维数组:
Array
(
[0] => Array
(
[id_produto] => 191
[categoria] => 7
[prazo] => 8
[desconto] => 45
)
[1] => Array
(
[id_produto] => 194
[categoria] => 7
[prazo] => 8
[desconto] => 39
)
[2] => Array
(
[id_produto] => 195
[categoria] => 7
[prazo] => 8
[desconto] => 39
)
Array
(
[0] => Array
(
[id_produto] => 191
[categoria] => 7
[pageviews] => 2103
)
[1] => Array
(
[id_produto] => 194
[categoria] => 7
[pageviews] => 2445
)
[2] => Array
(
[id_produto] => 195
[categoria] => 7
[pageviews] => 1560
)
Array
(
[0] => Array
(
[id_produto] => 191
[categoria] => 7
[pedidos] => 3
[valor] => 6501.583023
)
[1] => Array
(
[id_produto] => 194
[categoria] => 7
[pedidos] => 1
[valor] => 2217.968420
)
[2] => Array
(
[id_produto] => 197
[categoria] => 7
[pedidos] => 2
[valor] => 4405.517706
)
我想把它们结合起来,保持键' id_producto '和'categoria',并有如下内容:
Array
(
[0] => Array
(
[id_produto] => 191
[categoria] => 7
[prazo] => 8
[desconto] => 45
[pageviews] => 2103
[pedidos] => 3
[valor] => 6501.583023
)
[1] => Array
(
[id_produto] => 194
[categoria] => 7
[prazo] => 8
[desconto] => 39
[pageviews] => 2445
[pedidos] => 1
[valor] => 2217.968420
)
[2] => Array
(
[id_produto] => 195
[categoria] => 7
[prazo] => 8
[desconto] => 39
[pageviews] => 1560
[pedidos] => 2
[valor] => 4405.517706
)
我尝试了array_merge($array1,$array2,$array3)
和array_merge_recursive($array1,$array2,$array3)
,但它确实将它们复制到具有9个元素的数组中。下面的代码为我工作,但我正在寻找一个更快的解决方案,因为我有成千上万的id:
foreach($array1 as $arr1=>$a){
foreach($array2 as $arr2=>$b){
if($a['id_produto'] == $b['id_produto']){
$array1[$arr1]['pageviews'] = $b['pageviews'];
}
}
foreach($array3 as $arr3=>$c){
if($a['id_produto'] == $c['id_produto']){
$array1[$arr1]['pedidos'] = $c['pedidos'];
$array1[$arr1]['valor'] = $c['valor'];
}
}
}
键你的数组使用id_produto
,然后简单地使用php的内置数组函数,例如
array_replace_recursive($one, $two, $three)
首先,为什么你的代码很慢?假设您有1000个元素,您的代码将进行1000*(1000+1000)= 200万次迭代。这就是为什么。
如何使它更快?使用关联数组而不是普通数组,即使用id_produto
作为键,这样您就可以直接访问正确的元素,而不必在循环中进行循环。
首先转换array2和array3。array2:
的示例$new_array2 = array();
foreach ( $array2 as $row ) {
$new_array2[$row['id_produto']] = $row;
}
$array2 = $new_array2;
然后合并:
foreach ( $array1 as & $row ) {
$row['pageviews'] = $array2[$row['id_produto']['pageviews']];
$row['pedidos'] = $array3[$row['id_produto']['pedidos']];
$row['valor'] = $array3[$row['id_produto']['valor']];
}
这可能有用:
$merged = array_merge($a, $b, $c);
$fixed_merge = Array();
for($i=0; $i < count($merged); $i++){
echo $i;
$this_id = $merged[$i]['id_produto'];
if(isset($fixed_merge[$this_id])){
$fixed_merge[$this_id] = array_merge($fixed_merge[$this_id], $merged[$i]);
}else{
$fixed_merge[$this_id] = $merged[$i];
}
}
print_r($fixed_merge);
我将使用id_produto
作为临时键来填充第一个数组的结果数组。
在循环中,您可以在按这些临时键分组时安全地合并关联行数据。循环后,用array_values()
重新索引结果数组。
代码:(Demo) (Demo版本2——可能较慢)
$result = array_column($array1, null, 'id_produto');
foreach (array_merge($array2, $array3) as $row) {
$result[$row['id_produto']] = array_merge($result[$row['id_produto']] ?? [], $row);
}
var_export(array_values($result));
此方法将比@rlanvin的答案进行更多的函数调用(因此它应该在性能上稍微慢一些),但是不显式地命名特定数组中的特定目标列的优点是,每次修改传入数组的数量和质量时都不需要更改此代码片段。
这个解在n上有一个大0。如果这三个数组有1000行,那么array_column()
将迭代1000次而不调用迭代函数。然后foreach()
将迭代2000x并每次调用array_merge()
(可能将当前行与空数组合并)。因此,如果你有数百万行数据,那么只会有数百万次迭代。
以上也可以翻译为函数迭代。(演示)
var_export(
array_values(
array_reduce(
array_merge($array2, $array3),
function($result, $row) {
$result[$row['id_produto']] = array_merge($result[$row['id_produto']] ?? [], $row);
return $result;
},
array_column($array1, null, 'id_produto')
)
)
);
同样,您也可以使用本机递归函数。我不知道它在性能方面比较如何,但可读性可以说比其他选项要好。
代码(演示):
var_export(
array_values(
array_replace_recursive(
array_column($array1, null, 'id_produto'),
array_column($array2, null, 'id_produto'),
array_column($array3, null, 'id_produto')
)
)
);