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

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


当前回答

关联阵列

对于关联阵列,请使用unset:

$arr = array('a' => 1, 'b' => 2, 'c' => 3);
unset($arr['b']);

// RESULT: array('a' => 1, 'c' => 3)

数值数组

对于数值数组,请使用array_spling:

$arr = array(1, 2, 3);
array_splice($arr, 1, 1);

// RESULT: array(0 => 1, 1 => 3)

Note

对数值数组使用unset不会产生错误,但会打乱索引:

$arr = array(1, 2, 3);
unset($arr[1]);

// RESULT: array(0 => 1, 2 => 3)

其他回答

解决:

要删除一个元素,请使用unset():

未设置($array[3]);unset($array['fo']);

要删除多个不连续的元素,还可以使用unset():

未设置($array[3],$array[5]);取消设置($array['fo'],$array['bar']);

要删除多个连续元素,请使用array_splice():

array_拼接($array,$offset,$length);

进一步解释:

使用这些函数可以从PHP中删除对这些元素的所有引用。如果要在数组中保留一个键,但该键的值为空,请将空字符串分配给元素:

$array[3] = $array['foo'] = '';

除了语法之外,使用unset()和将“”赋值给元素之间还有逻辑上的区别。第一个表示This已不存在,而第二个表示This仍然存在,但其值为空字符串。

如果你在处理数字,分配0可能是更好的选择。因此,如果一家公司停止生产XL1000型链轮,它将更新库存:

unset($products['XL1000']);

然而,如果XL1000链轮暂时用完,但计划在本周晚些时候从工厂接收新的发货,则情况会更好:

$products['XL1000'] = 0;

如果取消设置()元素,PHP将调整数组,以便循环仍然正常工作。它不会压缩阵列以填充缺失的孔。这就是我们所说的所有数组都是关联的,即使它们看起来是数字。下面是一个示例:

// Create a "numeric" array
$animals = array('ant', 'bee', 'cat', 'dog', 'elk', 'fox');
print $animals[1];  // Prints 'bee'
print $animals[2];  // Prints 'cat'
count($animals);    // Returns 6

// unset()
unset($animals[1]); // Removes element $animals[1] = 'bee'
print $animals[1];  // Prints '' and throws an E_NOTICE error
print $animals[2];  // Still prints 'cat'
count($animals);    // Returns 5, even though $array[5] is 'fox'

// Add a new element
$animals[ ] = 'gnu'; // Add a new element (not Unix)
print $animals[1];  // Prints '', still empty
print $animals[6];  // Prints 'gnu', this is where 'gnu' ended up
count($animals);    // Returns 6

// Assign ''
$animals[2] = '';   // Zero out value
print $animals[2];  // Prints ''
count($animals);    // Returns 6, count does not decrease

要将数组压缩为填充密集的数字数组,请使用array_values():

$animals = array_values($animals);

或者,array_splice()会自动重新索引数组以避免留下洞:

// Create a "numeric" array
$animals = array('ant', 'bee', 'cat', 'dog', 'elk', 'fox');
array_splice($animals, 2, 2);
print_r($animals);
Array
(
    [0] => ant
    [1] => bee
    [2] => elk
    [3] => fox
)

如果您将数组用作队列,并希望从队列中删除项目,同时仍允许随机访问,则这非常有用。要安全地从数组中删除第一个或最后一个元素,请分别使用array_shift()和array_pop()。

此外,对于命名元素:

unset($array["elementName"]);

我来这里是因为我想看看是否有比使用unset($arr[$I])更优雅的解决方案来解决这个问题。令我失望的是,这些答案要么是错误的,要么没有涵盖所有边缘情况。

这就是array_diff()不起作用的原因。键在数组中是唯一的,而元素并不总是唯一的。

$arr = [1,2,2,3];

foreach($arr as $i => $n){
    $b = array_diff($arr,[$n]);
    echo "\n".json_encode($b);
}

后果

[2,2,3]
[1,3]
[1,2,2] 

如果两个元素相同,则将删除它们。这也适用于array_search()和array_flip()。

我看到了很多关于array_slice()和array_splice()的答案,但这些函数只适用于数值数组。如果这里没有回答这个问题,我知道所有的答案,所以这里有一个可行的解决方案。

$arr = [1,2,3];

foreach($arr as $i => $n){
    $b = array_merge(array_slice($arr,0,$i),array_slice($arr,$i+1));
    echo "\n".json_encode($b);
}

Results...

[2,3];
[1,3];
[1,2];

由于unset($arr[$i])将同时适用于关联数组和数值数组,所以这仍然不能回答这个问题。

这个解决方案是比较键和,使用一个同时处理数字和关联数组的工具。为此,我使用了array_diff_uassoc()。此函数用于比较回调函数中的按键。

$arr = [1,2,2,3];
//$arr = ['a'=>'z','b'=>'y','c'=>'x','d'=>'w'];
foreach($arr as $key => $n){
    $b = array_diff_uassoc($arr, [$key=>$n], function($a,$b) {
        if($a != $b){
            return 1;
        }
    });
    echo "\n".json_encode($b);
}    

后果

[2,2,3];
[1,2,3];
[1,2,2];

['b'=>'y','c'=>'x','d'=>'w'];
['a'=>'z','c'=>'x','d'=>'w'];
['a'=>'z','b'=>'y','d'=>'w'];
['a'=>'z','b'=>'y','c'=>'x'];
$key = array_search($needle, $array);
if ($key !== false) {
    unset($array[$key]);
}

关联阵列

对于关联阵列,请使用unset:

$arr = array('a' => 1, 'b' => 2, 'c' => 3);
unset($arr['b']);

// RESULT: array('a' => 1, 'c' => 3)

数值数组

对于数值数组,请使用array_spling:

$arr = array(1, 2, 3);
array_splice($arr, 1, 1);

// RESULT: array(0 => 1, 1 => 3)

Note

对数值数组使用unset不会产生错误,但会打乱索引:

$arr = array(1, 2, 3);
unset($arr[1]);

// RESULT: array(0 => 1, 2 => 3)