如何通过嵌套foreach循环在id匹配时将数组数据互传?
问题原因与解决方案
问题根源
PHP的foreach循环默认是值传递,遍历数组时拿到的$nameArr是原数组元素的副本,不是原元素的引用。你在循环里修改$nameArr,只是改动了这个临时副本,原数组$arr1里的元素根本没被影响,所以最后输出的还是原数组内容。
修复方案
方案1:使用引用遍历
在foreach的变量前加&符号,让$nameArr成为原数组元素的引用,修改它就会直接改动原数组:
$arr1 = [['id' => 123, 'name' => 'joe'], ['id' => 321, 'name' => 'bloggo']]; $arr2 = [['id'=> 123, 'job' => 'bin man'], ['id'=> 999, 'job' => 'salary man']]; foreach($arr1 as &$nameArr) { // 给变量添加&引用 foreach($arr2 as $jobArr) { if ($nameArr['id'] == $jobArr['id']) { $nameArr['job'] = $jobArr['job']; } } } unset($nameArr); // 用完引用后销毁,避免后续变量污染 echo json_encode($arr1);
执行后输出:[{"id":123,"name":"joe","job":"bin man"},{"id":321,"name":"bloggo"}]
方案2:通过数组索引修改
不使用引用,而是遍历数组的键和值,通过键直接修改原数组元素:
$arr1 = [['id' => 123, 'name' => 'joe'], ['id' => 321, 'name' => 'bloggo']]; $arr2 = [['id'=> 123, 'job' => 'bin man'], ['id'=> 999, 'job' => 'salary man']]; foreach($arr1 as $key => $nameArr) { foreach($arr2 as $jobArr) { if ($nameArr['id'] == $jobArr['id']) { $arr1[$key]['job'] = $jobArr['job']; // 通过键直接操作原数组 break; // 找到匹配项后跳出内层循环,提升效率 } } } echo json_encode($arr1);
这个方案无需处理引用销毁问题,更安全。
优化建议(数组量大时适用)
双层循环效率较低,可先把$arr2转换成以id为键的关联数组,匹配时只需一次循环:
$arr1 = [['id' => 123, 'name' => 'joe'], ['id' => 321, 'name' => 'bloggo']]; $arr2 = [['id'=> 123, 'job' => 'bin man'], ['id'=> 999, 'job' => 'salary man']]; // 将arr2转为id映射job的数组 $jobMap = []; foreach($arr2 as $item) { $jobMap[$item['id']] = $item['job']; } // 遍历arr1直接匹配赋值 foreach($arr1 as &$nameArr) { if (isset($jobMap[$nameArr['id']])) { $nameArr['job'] = $jobMap[$nameArr['id']]; } } unset($nameArr); echo json_encode($arr1);
这种方式时间复杂度从O(n*m)降到O(n+m),数据量大时性能提升明显。
内容的提问来源于stack exchange,提问作者physicsboy
相关产品推荐
相关产品推荐

