此问题在此处已有答案:
Keep array rows where a column value is found in a second flat array(4个答案)
8小时前关门了。
在下面的示例中,目标是根据一个数组从另一个数组中选择某些元素(选择id):
$cars = [
0 => ["id" => 1, "name" => "FORD"],
1 => ["id" => 2, "name" => "BMW"],
2 => ["id" => 3, "name" => "FIAT"],
3 => ["id" => 4, "name" => "RENAULT"],
4 => ["id" => 5, "name" => "BENTLEY"],
];
包含ID选择的数组:
$selection = [
0 => "1",
1 => "3",
2 => "4"
]
预期产出:
$cars = [
0 => ["id" => 1, "name" => "FORD"],
1 => ["id" => 3, "name" => "FIAT"],
2 => ["id" => 4, "name" => "RENAULT"],
];
尝试举例说明:
$result = array();
foreach($cars as $key => $val) {
if ($val['id'] === $selection[$key]) {
$result[] = $cars[$key];
}
}
2条答案
按热度按时间8ehkhllq1#
你可以利用php的数组filter函数。
主要的“技巧”是遍历所有的汽车,检查它们对应的ID是否在选择中。array_filter()需要一个数组和一个函数。函数检查当前的汽车ID是否是选择的一部分。当filter函数返回true时,保留该值,否则丢弃该值。
您也可以反过来,或者使用两个嵌套的foreach循环来创建一个新数组,但这样做更简单。
Online Demo
5fjcxozz2#
虽然使用
array_filter
的答案肯定可以完成工作,但它涉及到每次迭代时的in_array
函数调用。对于小数据,这不是问题。对于较大的数据集,在一次迭代中重复的函数调用可能会导致性能下降。在可能的情况下,最好“预处理”数据,以便使用 * 语言构造 * 代替 * 函数 * 进行更轻松的操作。您可以使用
array_flip($selection)
“启用”索引查找,即通过交换键和值,然后执行简单的键查找:对于较大的数据,isset($selection[$id])
的性能明显优于in_array($id, $selection)
,我们实际上只关心(唯一的)密钥。作为过滤的替代方法,您可以使用
array_column()
* 按所需键重新索引数组 *,其中null
用于列键(返回完整数组),id
用于索引键:然后,我们就差一个
array_intersect_key
就可以从 *source数组 * 中提取 selection 了:在这里我们翻转
$selection
以交叉键。结果如预期。请参见此方法的演示。最后,这里是一个不带丢弃变量的一行程序(格式便于阅读):注意:生成的数组将以汽车的实际
id
作为索引键;而不是默认的零索引键。如果稍后在代码中用源数组交叉引用选定的汽车,请记住这一点;并且可能从一开始就通过适当的ID来索引汽车。比较两种方法:
array_filter()
导致$cars
的1次迭代,每个数组成员1次函数调用;然后,$selection
的迭代次数与汽车的数量相同,in_array
函数调用将每个$selection
成员与当前汽车ID进行比较。这个答案中的方法1.在
$cars
上迭代一次,用于简单的重新索引;2.对于键/值翻转,在$selection
上迭代一次;然后3.针对交集迭代每个列表的关键字(AFAIK对两个列表排序,然后并行比较它们)。P.S.当然,简单的
foreach
循环也可以工作。要修复您的初始尝试,如下所示:我会在需要“基本”性能的重要数据集(或较长的比较列表)中使用此方法(如果有人比较了PHP 8.x中的这些方法,请分享结果)。