在 foreach 循环内有条件地过滤二维数组不会删除所有过滤的行

问题描述 投票:0回答:2

我有这个数组

$array = Array(
    '0' => Array('id' => '5', 'class' => 'A'),
    '1' => Array('id' => '53', 'class' => 'B'),
    '2' => Array('id' => '2', 'class' => 'C'),
);

我想要,例如,如果类是“B”,则仅保留密钥 1;

这是我的代码,但它无法正常工作:

foreach ($array as $key => $values) {
    $array[$key]['description'] = 'dadadadad';
    if ($values['class'] == 'B') {
        $array = array_intersect_key($array, array_flip(Array($key)));
    }   
}
php arrays filter foreach copy
2个回答
2
投票

使用

array_filter

$a = array_filter($a, function($item) {
  return $item['class'] === 'B';
});

根据文档,使用 array_filter 时“保留数组键”。


0
投票

我想了解为什么我的代码不起作用。 - @OsomA

您的代码做了两件事:

  1. 它无条件地向迭代的每一行添加一个
    description
    键控元素,然后
  2. 当遇到符合条件的行时,您可以过滤原始输入数组以仅保留符合条件的行的元素。

我认为让你陷入循环的部分(双关语)是 PHP 的

foreach()
迭代输入数组的 copy。 这意味着当您到达 B 行时,您会过滤输入数组,但
foreach()
并不关心,因为它正在遍历原始数组的副本。

现在,PHP 确实有办法告诉

foreach()
循环迭代原始数组而不是副本。 为此,您可以写
foreach ($array as $key => &$value) {
。 但你也不想这样做——如果数组中有符合条件的行,你会遇到无限循环,因为每次你有条件地重新定义
$array
时,数组“指针”都会重置,并且
foreach()
将不断重启。

我不确定你的实际编码需求是什么,但是如果你不希望从无条件声明中产生额外的元素,那么可以在过滤后简单地用

break
终止你的循环,因为过滤器总是会减少数组到单行。 事实上,我将演示一个无功能的过滤脚本。 演示

$array = [
    ['id' => '5', 'class' => 'A'],
    ['id' => '53', 'class' => 'B'],
    ['id' => '2', 'class' => 'C'],
];

foreach ($array as $key => $values) {
    $array[$key]['description'] = 'dadadadad';
    if ($values['class'] == 'B') {
        $array = [$key => $array[$key]];
        break;
    }
}
var_export($array);
© www.soinside.com 2019 - 2024. All rights reserved.