php 使用平面白名单数组从对象的关联数组中删除元素

bsxbgnwa  于 12个月前  发布在  PHP
关注(0)|答案(6)|浏览(95)

我需要使用白名单值的平面数组来过滤对象数组。

$objects = [
    3 => (object) ['tid' => 3],
    12 => (object) ['tid' => 12],
    9 => (object) ['tid' => 9],
];

$whitelist = [3, 4, 9, 11];

白名单不包含12,因此应删除该对象。
所需输出:

[
    3 => (object) ['tid' => 3],
    9 => (object) ['tid' => 9],
]
vaqhlq81

vaqhlq811#

你可以这样做:

$keys = array_map(function($val) { return $val['value']; }, $first);
$result = array_intersect_key(array_flip($keys), $second);

array_map调用将从$first中提取 value 值,以便$keys是这些值的数组。然后使用array_intersect_key获取$keys(翻转以使用键作为值,反之亦然)和第二个数组$second的交集。

hpxqektj

hpxqektj2#

经过一些清理,我很清楚我需要什么,这一点整理出来:

foreach ($second_array as $foo) {
  if (!in_array($foo->tid, $first_array)) {
    unset($second_array[$foo->tid]);
  }
}
kokeuurv

kokeuurv3#

对于关联数组,可以使用简单的键允许列表过滤器:

$arr = array('a' => 123, 'b' => 213, 'c' => 321); 
$allowed = array('b', 'c'); 

print_r(array_intersect_key($arr, array_flip($allowed)));

将返回:

Array 
( 
    [b] => 213 
    [c] => 321 
)
r1wp621o

r1wp621o4#

因为你想过滤你的数组(通过其他数组中包含的所有键),你可以使用array_filter函数。

$first  = [3,4,9,11];
$second = [ 3 => 'A' , 9 => 'B' , 12 => 'C'];

$clean = array_filter($second, function($key)use($first){
            return in_array($key,$first);
          },
           ARRAY_FILTER_USE_KEY);

// $clean = [ 3 => 'A' , 9 => 'B'];

ARRAY_FILTER_USE_KEY常量是函数的第三个参数,因此$key实际上是回调中$second数组的键。这可以调整:
确定哪些参数被发送到回调的标志(第三个参数):

ARRAY_FILTER_USE_KEY - pass key as the only argument to callback instead of the value
ARRAY_FILTER_USE_BOTH - pass both value and key as arguments to callback instead of the value

默认值为0,它将把value作为唯一的参数传递给callback。

2jcobegt

2jcobegt5#

array_filter中使用回调
如果你的第一个数组确实是这样的,你可能想把它改成一个更有用的一维数组,所以你可以使用一个简单的in_array作为回调函数的一部分:

$values = array_map('reset',$array);

我现在才看到keys和object-ids是一样的:

$result =  array_intersect_key($objectarray,array_flip(array_map('reset',$array)));
c0vxltue

c0vxltue6#

要将每个对象中的tid列值与白名单值进行比较,不需要翻转、列提取或in_array()的迭代调用。调用array_uintersect()比较不同深度的数组。自定义函数中的$a$b可以来自任意一个输入数组,因此请先尝试访问object属性,如果该属性不存在,则可以安全地假设该值来自平面白名单数组。
代码:(Demo

$objects = [
    3 => (object) ['tid' => 3],
    12 => (object) ['tid' => 12],
    9 => (object) ['tid' => 9],
];

$whitelist = [3, 4, 9, 11];

var_export(
    array_uintersect($objects, $whitelist, fn($a, $b) => ($a->tid ?? $a) <=> ($b->tid ?? $b))
);

也就是说,通过将objectArray的键与白名单数组值进行比较,这个问题中的数据有助于更快的计算。在这种情况下,最快的方法是翻转白名单并调用array_intersect_key(),这在此答案之前已经演示过了。

相关问题