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

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


当前回答

如果您有一个数字索引数组,其中所有值都是唯一的(或者它们是非唯一的,但您希望删除特定值的所有实例),您可以简单地使用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。

其他回答

如果指定了索引:

$arr = ['a', 'b', 'c'];
$index = 0;    
unset($arr[$index]);  // $arr = ['b', 'c']

如果我们有值而不是索引:

$arr = ['a', 'b', 'c'];

// search the value to find index
// Notice! this will only find the first occurrence of value
$index = array_search('a', $arr);

if($index !== false){
   unset($arr[$index]);  // $arr = ['b', 'c']
}

if条件是必要的因为如果找不到索引,unset()将自动删除数组的第一个元素,这不是我们想要的。

unset()销毁指定的变量。

函数内部unset()的行为可能会因试图销毁的变量类型而异。

如果函数内部的全局变量未设置(),则只销毁局部变量。调用环境中的变量将保持与调用unset()之前相同的值。

<?php
    function destroy_foo()
    {
        global $foo;
        unset($foo);
    }

    $foo = 'bar';
    destroy_foo();
    echo $foo;
?>

以上代码的答案将为bar。

要取消设置()函数内部的全局变量,请执行以下操作:

<?php
    function foo()
    {
        unset($GLOBALS['bar']);
    }

    $bar = "something";
    foo();
?>

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

我只想说,我有一个具有可变属性的特定对象(它基本上映射了一个表,我正在更改表中的列,因此反映表的对象中的属性也会发生变化):

class obj {
    protected $fields = array('field1','field2');
    protected $field1 = array();
    protected $field2 = array();
    protected loadfields(){}
    // This will load the $field1 and $field2 with rows of data for the column they describe
    protected function clearFields($num){
        foreach($fields as $field) {
            unset($this->$field[$num]);
            // This did not work the line below worked
            unset($this->{$field}[$num]); // You have to resolve $field first using {}
        }
    }
}

$fields的全部目的只是,所以当代码发生更改时,我不必查看代码中的任何地方,我只需查看类的开头并更改属性列表和$fields数组内容以反映新属性。

  // Our initial array
  $arr = array("blue", "green", "red", "yellow", "green", "orange", "yellow", "indigo", "red");
  print_r($arr);

  // Remove the elements who's values are yellow or red
  $arr = array_diff($arr, array("yellow", "red"));
  print_r($arr);

这是上面代码的输出:

Array
(
    [0] => blue
    [1] => green
    [2] => red
    [3] => yellow
    [4] => green
    [5] => orange
    [6] => yellow
    [7] => indigo
    [8] => red
)

Array
(
    [0] => blue
    [1] => green
    [4] => green
    [5] => orange
    [7] => indigo
)

现在,array_values()将很好地重新索引数字数组,但它将从数组中删除所有键字符串,并用数字替换它们。如果需要保留键名称(字符串),或者如果所有键都是数字,则重新索引数组,请使用array_merge():

$arr = array_merge(array_diff($arr, array("yellow", "red")));
print_r($arr);

输出

Array
(
    [0] => blue
    [1] => green
    [2] => green
    [3] => orange
    [4] => indigo
)