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

发布于 2024-09-28 07:42:37 字数 361 浏览 7 评论 0原文

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

$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],
]

I need to filter an array of objects using a flat array of whitelisted values.

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

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

The whitelist doesn't contain 12, so that object should be removed.

Desired output:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

酒浓于脸红 2024-10-05 07:42:37

您可以这样做:

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

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

You can do this:

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

The array_map call will extract the value values from $first so that $keys is an array of these values. Then array_intersect_key is used to get the intersection of $keys (flipped to use the keys as values and vice versa) and the second array $second.

爱人如己 2024-10-05 07:42:37

经过一番清理后,我很清楚我需要什么,这一点就解决了:

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

After some clean up it was pretty clear what I needed, and this little bit sorts it out:

foreach ($second_array as $foo) {
  if (!in_array($foo->tid, $first_array)) {
    unset($second_array[$foo->tid]);
  }
}   
執念 2024-10-05 07:42:37

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

$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 
)

For associative arrays it can be used simple key allow-list filter:

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

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

Will return:

Array 
( 
    [b] => 213 
    [c] => 321 
)
快乐很简单 2024-10-05 07:42:37

由于您想过滤数组(通过另一个数组中包含的所有键),您可以使用 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 - 将键而不是值作为唯一参数传递给回调
ARRAY_FILTER_USE_BOTH - 将值和键作为参数传递给回调而不是值

默认值为 0,它将把值作为唯一参数传递给回调
相反。

Since you want to filter your array (by all keys that are contained in the other array), you may use the array_filter function.

$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'];

The ARRAY_FILTER_USE_KEY constant is the 3rd parameter of the function so that $key is actually the key of the $second array in the callback. This can be adjusted:

Flag determining what arguments are sent to callback (3rd argument):

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

Default is 0 which will pass value as the only argument to callback
instead.

长发绾君心 2024-10-05 07:42:37

array_filter 中使用回调

如果你的第一个数组确实像这样,你可能想要将其更改为更可用的一维数组,因此您使用简单的 in_array 作为回调的一部分:

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

我现在只看到键 &对象 ID 是相似的:

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

Use a callback in array_filter

If your first array really looks like that, you might want to alter it in a more usable one-dimensional array, so you use a simple in_array as part of your callback:

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

I only now see that the keys & object-ids are alike:

$result =  array_intersect_key($objectarray,array_flip(array_map('reset',$array)));
四叶草在未来唯美盛开 2024-10-05 07:42:37

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

代码:(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() ,这比这个答案早得多。

To compare the tid column values in each object against the whitelist values, no flipping, column extraction, or iterated calls of in_array() are necessary. Call array_uintersect() to compare the arrays of different depths. $a and $b in the custom function can come from either input array, so try to access the object property first and if it doesn't exist, then it is safe to assume that the value comes from the flat, whitelist array.

Code: (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))
);

That said, the data in this question lends itself to faster computation by comparing the objectArray's keys against the whitelist array values. In this context, the fastest approach will be to flip the whitelist and call array_intersect_key() which was demonstrated much earlier than this answer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文