有没有一种简单的方法可以使用PHP从数组中删除元素,从而foreach($array)不再包含该元素?

我以为将其设置为null就可以了,但显然它不起作用。


当前回答

unset()数组中的多个碎片元素

虽然这里多次提到unset(),但还需要提到的是,unset(()接受多个变量,从而可以在一次操作中轻松删除数组中的多个非连续元素:

// Delete multiple, noncontiguous elements from an array
$array = [ 'foo', 'bar', 'baz', 'quz' ];
unset( $array[2], $array[3] );
print_r($array);
// Output: [ 'foo', 'bar' ]

动态取消设置()

unset()不接受要删除的键数组,因此下面的代码将失败(但这会使动态使用unset(()稍微容易一些)。

$array = range(0,5);
$remove = [1,2];
$array = unset( $remove ); // FAILS: "unexpected 'unset'"
print_r($array);

相反,unset()可以在foreach循环中动态使用:

$array = range(0,5);
$remove = [1,2];
foreach ($remove as $k=>$v) {
    unset($array[$v]);
}
print_r($array);
// Output: [ 0, 3, 4, 5 ]

通过复制数组来删除数组键

还有一种做法尚待提及。有时,消除某些数组键的最简单方法是将$array1复制到$array2中。

$array1 = range(1,10);
foreach ($array1 as $v) {
    // Remove all even integers from the array
    if( $v % 2 ) {
        $array2[] = $v;
    }
}
print_r($array2);
// Output: [ 1, 3, 5, 7, 9 ];

显然,同样的做法适用于文本字符串:

$array1 = [ 'foo', '_bar', 'baz' ];
foreach ($array1 as $v) {
    // Remove all strings beginning with underscore
    if( strpos($v,'_')===false ) {
        $array2[] = $v;
    }
}
print_r($array2);
// Output: [ 'foo', 'baz' ]

其他回答

unset($array[$index]);

有两种方法可以删除数组的第一项,同时保持索引的顺序,如果您不知道第一项的键名。

解决方案#1

// 1 is the index of the first object to get
// NULL to get everything until the end
// true to preserve keys
$array = array_slice($array, 1, null, true);

解决方案#2

// Rewinds the array's internal pointer to the first element
// and returns the value of the first array element.
$value = reset($array);
// Returns the index element of the current array position
$key = key($array);
unset($array[$key]);

对于此示例数据:

$array = array(10 => "a", 20 => "b", 30 => "c");

您必须获得以下结果:

array(2) {
  [20]=>
  string(1) "b"
  [30]=>
  string(1) "c"
}

Edit

如果无法将其视为对象位于该数组中,则需要添加检查:

if(in_array($object,$array)) unset($array[array_search($object,$array)]);

原始答案

如果要通过引用数组中的特定对象来删除该对象,可以执行以下操作:

unset($array[array_search($object,$array)]);

例子:

<?php
class Foo
{
    public $id;
    public $name;
}

$foo1 = new Foo();
$foo1->id = 1;
$foo1->name = 'Name1';

$foo2 = new Foo();
$foo2->id = 2;
$foo2->name = 'Name2';

$foo3 = new Foo();
$foo3->id = 3;
$foo3->name = 'Name3';


$array = array($foo1,$foo2,$foo3);
unset($array[array_search($foo2,$array)]);

echo '<pre>';
var_dump($array);
echo '</pre>';
?>

结果:

array(2) {
[0]=>
    object(Foo)#1 (2) {
        ["id"]=>
        int(1)
        ["name"]=>
        string(5) "Name1"
    }
[2]=>
    object(Foo)#3 (2) {
        ["id"]=>
        int(3)
        ["name"]=>
        string(5) "Name3"
    }
}

请注意,如果对象多次出现,则只会在第一次出现时删除它!

如果您有一个数字索引数组,其中所有值都是唯一的(或者它们是非唯一的,但您希望删除特定值的所有实例),您可以简单地使用array_diff()来删除匹配元素,如下所示:

$my_array = array_diff($my_array, array('Value_to_remove'));

例如:

$my_array = array('Andy', 'Bertha', 'Charles', 'Diana');
echo sizeof($my_array) . "\n";
$my_array = array_diff($my_array, array('Charles'));
echo sizeof($my_array);

这将显示以下内容:

4
3

在本例中,值为“Charles”的元素被移除,这可以通过sizeof()调用进行验证,该调用报告初始数组的大小为4,移除后为3。

如果您必须删除数组中的多个值,并且该数组中的条目是对象或结构化数据,那么array_filter()是最佳选择。那些从回调函数返回true的条目将被保留。

$array = [
    ['x'=>1,'y'=>2,'z'=>3], 
    ['x'=>2,'y'=>4,'z'=>6], 
    ['x'=>3,'y'=>6,'z'=>9]
];

$results = array_filter($array, function($value) {
    return $value['x'] > 2; 
}); //=> [['x'=>3,'y'=>6,z=>'9']]