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',
  ),
)