Php 按第二个数组中的值筛选数组 **我编辑了这篇文章来展示我是如何使用array\u search让代码工作的
我有一个数组,Php 按第二个数组中的值筛选数组 **我编辑了这篇文章来展示我是如何使用array\u search让代码工作的,php,arrays,filter,array-filter,Php,Arrays,Filter,Array Filter,我有一个数组,$arr1,有5列: key id name style age whim 0 14 bob big 33 no 1 72 jill big 22 yes 2 39 sue yes 111 yes 3 994 lucy small 23 no 4 15 sis med 24 no 5 16 maj
$arr1
,有5列:
key id name style age whim
0 14 bob big 33 no
1 72 jill big 22 yes
2 39 sue yes 111 yes
3 994 lucy small 23 no
4 15 sis med 24 no
5 16 maj med 87 yes
6 879 Ike larg 56 no
7 286 Jed big 23 yes
此阵列位于缓存中,而不是数据库中
然后我有第二个数组,其中包含id值列表-
$arr2 = (0=>14, 1=>72, 2=>8790)
如何筛选$arr1
,使其仅返回具有$arr2
中id值的行
我的代码如下所示:
$arr1 = new CachedStuff(); // get cache
$resultingArray = []; // create an empty array to hold rows
$filter_function = function ($row) use ($arr2) {
return (array_search($row['id'], $arr2));
};
$resultingArrayIDs = $arr1->GetIds($filter_function, $resultingArray);
这给了我两个输出:$resultingArray和$ResultingArrayId,两者都表示$arr1和$arr2的交集。如果我正确理解了您的问题和数据结构,这样做应该可以:
$dataArray = [
[ 'key' => 0, 'id' => 14 , 'name' => 'bob' , 'style' => 'big' , 'age' => 33 , 'whim' => 'no' ],
[ 'key' => 1, 'id' => 72 , 'name' => 'jill' , 'style' => 'big' , 'age' => 22 , 'whim' => 'yes' ],
[ 'key' => 2, 'id' => 39 , 'name' => 'sue' , 'style' => 'yes' , 'age' => 111 , 'whim' => 'yes' ],
[ 'key' => 3, 'id' => 994 , 'name' => 'lucy' , 'style' => 'small' , 'age' => 23 , 'whim' => 'no' ],
[ 'key' => 4, 'id' => 15 , 'name' => 'sis' , 'style' => 'med' , 'age' => 24 , 'whim' => 'no' ],
[ 'key' => 5, 'id' => 16 , 'name' => 'maj' , 'style' => 'med' , 'age' => 87 , 'whim' => 'yes' ],
[ 'key' => 6, 'id' => 879 , 'name' => 'Ike' , 'style' => 'larg' , 'age' => 56 , 'whim' => 'no' ],
[ 'key' => 7, 'id' => 286 , 'name' => 'Jed' , 'style' => 'big' , 'age' => 23 , 'whim' => 'yes' ]
];
$filterArray = [14, 72, 879];
$resultArray = array_filter( $dataArray, function( $row ) use ( $filterArray ) {
return in_array( $row[ 'id' ], $filterArray );
} );
然而,您的问题似乎表明这些数据可能来自数据库;对吗?如果是这样,在数据库级别预过滤结果可能会更有效。通过在SELECT查询中添加一个表示布尔值的字段,该值表示一行是否与您的筛选器ID匹配,或者干脆不返回其他行。一种方法是使用
foreach
循环array\u search()
正如@DecentDabbler所提到的-如果数据来自数据库,则在上的中使用,其中将允许您仅检索相关数据
另一种过滤方法是使用数组函数
- array\u column将id列的值提取到数组中
- 数组_intersect返回$arr1['id']和$arr2中的元素
- 数组\u flip翻转生成的数组,使$arr1中的索引指示$arr1和$arr2中的元素
$arr1 = [ [ 'id' => 14, 'name' => 'bob'],
['id' => 72, 'name' => 'jill'],
['id' => 39, 'name' => 'sue'],
['id' => 994, 'name' => 'lucy'],
['id' => 879, 'name'=> 'large']];
$arr2 = [ 14,72,879 ];
$intersection = array_flip(array_intersect(array_column($arr1,'id'),$arr2));
foreach ($intersection as $i) {
var_dump($arr1[$i]);;
}
在第二个/过滤数组上使用迭代检查的问题是,随着数组大小的增加,它将失去效率
通过将新键指定给第一个数组,并将筛选数组的值翻转为键,可以对数组运行一次性筛选/相交,然后对输出数组重新编制索引
我的方法不调用foreach()
循环,并且没有迭代条件
代码:()
或者像这样写一行:
var_export(array_values(array_intersect_key(array_column($arr1,null,'id'),array_flip($arr2))));
输出:
array (
0 =>
array (
'key' => 0,
'id' => 14,
'name' => 'bob',
'style' => 'big',
'age' => 33,
'whim' => 'no',
),
1 =>
array (
'key' => 1,
'id' => 72,
'name' => 'jill',
'style' => 'big',
'age' => 22,
'whim' => 'yes',
),
2 =>
array (
'key' => 6,
'id' => 879,
'name' => 'Ike',
'style' => 'larg',
'age' => 56,
'whim' => 'no',
),
)
@伊恩:我在这个问题上是一个迟到的人,所以我没有得到任何提前投票的施舍。我想澄清一下,如果我的答案解释得不够好,我的答案是有效的,因为它不会在循环中执行阵列扫描。DecentDabbler和Erwin的解决方案在循环的每次迭代中都执行部分(可能是完整的阵列扫描),这可能代价高昂。user2182349的方法是正确的,但是对临时值而不是临时键执行了过滤过程,因此必须调用foreach()
循环来生成所需的输出数组。最后一点需要注意的是,如果不关心临时键,可以跳过最后一次调用array\u values()
并继续执行代码中的下一个过程。@ian和mickmackusa:是的,这个答案比我的解决方案快得多,尤其是在处理大型缓存集和大型过滤器集时。@mickmackusa和Desting Dabbler:感谢你们两位。我已经编辑了上面的代码,以显示我如何使用array_search来解决我的问题。但是,我很感兴趣的是,这种方法是否可以应用于提高效率。通过查看我更新的函数,你们中的任何一个都能看出吗?@ian您使用array\u search()
的方式不是“零安全”的,因为您的条件是对搜索结果进行松散比较,所以(true)0
返回值将被错误地计算为false。您需要对false
进行文字/严格检查,才能正确使用此函数调用。此外,我再次澄清,使用迭代的array\u search()
或in\u array()
方法的效率不如对两个数组进行单一比较的方法。请使用我的方法以获得最佳效率。谢谢@delegate Dabbler,它实际上来自缓存。
var_export(array_values(array_intersect_key(array_column($arr1,null,'id'),array_flip($arr2))));
array (
0 =>
array (
'key' => 0,
'id' => 14,
'name' => 'bob',
'style' => 'big',
'age' => 33,
'whim' => 'no',
),
1 =>
array (
'key' => 1,
'id' => 72,
'name' => 'jill',
'style' => 'big',
'age' => 22,
'whim' => 'yes',
),
2 =>
array (
'key' => 6,
'id' => 879,
'name' => 'Ike',
'style' => 'larg',
'age' => 56,
'whim' => 'no',
),
)