题 PHP:从数组中删除元素


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

我认为把它设置为 null 会这样做,但显然它不起作用。


1972
2017-12-15 20:28


起源


我不认为康拉德的回答是对所述问题最简单的回答。同 unset() 数组上的迭代将不再包含已删除的值。 OTOH,Stevan的回答是充实的,实际上,这是我正在寻找的答案 - 但不是OP :) - brandizzi
@danip在手册中很容易找到并不排除StackOverflow上的问题。如果问题是 重复 StackOverflow问题,那么它可能不属于这里。 StackOverflow是查找答案的好地方,甚至在查看手册之前。 - Dan Nissenbaum
@unset($阵列[$键]); $ array = array_values($ array); - trojan
关于在foreach循环中删除它的相关问题: stackoverflow.com/questions/1949259/... - Legolas
如果要从数组数组(关联数组)中删除键,请参阅解决方案 stackoverflow.com/a/47978980/1045444 - Somnath Muluk


答案:


删除数组元素有不同的方法,其中一些对某些特定任务比其他任务更有用。

删除一个数组元素

如果您只想删除一个可以使用的数组元素 unset() 或替代 array_splice()

此外,如果您有值并且不知道删除可以使用的元素的键 array_search() 得到钥匙。

unset() 方法

请注意,使用时 unset() 数组键不会更改/重新索引。如果要重新索引可以使用的键 array_values() 后 unset() 它将所有键转换为从0开始的数字枚举键。

<?php

    $array = array(0 => "a", 1 => "b", 2 => "c");
    unset($array[1]);
               //↑ Key which you want to delete

?>

产量

Array (
    [0] => a
    [2] => c
)

array_splice() 方法

如果你使用 array_splice() 键将自动重新索引,但关联键不会改变而不是 array_values() 这会将所有键转换为数字键。

array_splice() 需要偏移,而不是关键!作为第二个参数。

<?php

    $array = array(0 => "a", 1 => "b", 2 => "c");
    array_splice($array, 1, 1);
                       //↑ Offset which you want to delete

?>

产量

Array (
    [0] => a
    [1] => c
)

array_splice() 与...一样 unset() 通过引用获取数组,这意味着您不希望将这些函数的返回值分配回数组。

删除多个数组元素

如果要删除多个数组元素而不想调用 unset() 要么 array_splice() 您可以多次使用这些功能 array_diff() 要么 array_diff_key() 取决于您是否知道要删除的元素的值或键。

array_diff() 方法

如果您知道要删除的数组元素的值,则可以使用 array_diff()。和以前一样 unset() 它不会改变/重新索引数组的键。

<?php

    $array = array(0 => "a", 1 => "b", 2 => "c");
    $array = array_diff($array, ["a", "c"]);
                              //└────────┘→ Array values which you want to delete

?>

产量

Array (
    [1] => b
)

array_diff_key() 方法

如果您知道要删除的元素的键,则需要使用 array_diff_key()。在这里,您必须确保将键作为键传递到第二个参数而不是值。否则,你必须翻转数组 array_flip()。而且这里的密钥不会改变/重新索引。

<?php

    $array = array(0 => "a", 1 => "b", 2 => "c");
    $array = array_diff_key($array, [0 => "xy", "2" => "xy"]);
                                   //↑           ↑ Array keys which you want to delete
?>

产量

Array (
    [1] => b
)

此外,如果你想使用 unset() 要么 array_splice() 删除具有相同值的多个元素 array_keys() 获取特定值的所有键,然后删除所有元素。


2229
2017-12-15 21:25



如果你有<?php $ x = array(1,2,3,4);未设置($ X [2]);后续代码var_dump($ X); // array(3){[0] => int(0),[1] => int(2),[3] => int(4),}?> - Alexandru Rada
@AlexandruRada不,你说“不要用这个” - 这只是胡说八道。将数组视为字典时,可以安全地使用此方法 - 字典。只有当您期望连续的数字索引时,您才需要使用其他东西。 - Konrad Rudolph
@Alexander使用 array_splice,如其他答案中所述。 - Konrad Rudolph
@AlexandruRada你无法拥有 array (3) { [0]=>int(0) ... 当你 unset($x[2]) 从 $x = array(1, 2, 3, 4); 结果 必须 是 var_dump($x); // array(3) { [0]=> int(1) [1]=> int(2) [3]=> int(4) } (这可能是错字) - inemanja
array_filter也是一种可行的方法。特别好,如果你不想改变数组,但它也没有重新索引,这可能是json_encode的问题。 php.net/manual/en/function.json-encode.php#94157 - dotnetCarpenter


应当指出的是 unset() 将保持索引不变,这是您在使用字符串索引(数组作为哈希表)时所期望的,但在处理整数索引数组时可能会非常令人惊讶:

$array = array(0, 1, 2, 3);
unset($array[2]);
var_dump($array);
/* array(3) {
  [0]=>
  int(0)
  [1]=>
  int(1)
  [3]=>
  int(3)
} */

$array = array(0, 1, 2, 3);
array_splice($array, 2, 1);
var_dump($array);
/* array(3) {
  [0]=>
  int(0)
  [1]=>
  int(1)
  [2]=>
  int(3)
} */

所以 array_splice() 如果你想规范化整数键,可以使用它。另一种选择是使用 array_values() 后 unset()

$array = array(0, 1, 2, 3);

unset($array[2]);
$array = array_values($array);
var_dump($array);
/* array(3) {
  [0]=>
  int(0)
  [1]=>
  int(1)
  [2]=>
  int(3)
} */

1302
2017-08-02 15:57



值得注意的是,当你使用array_splice()时,你需要知道OFFSET,而不是键,但是你想要删除的元素的偏移量(!) - Tom
@Tom:对于常规数组(连续整数索引),偏移量是索引。那是在哪里 array_splice 可以有意义(其中包括)。 - Stefan Gehrig
是的,当然,但是如果你在使用拼接之前篡改阵列,那就要记住了 - Tom
从一个从巨大阵列中删除大量元素的基本测试来看,array_splice似乎更快,内存更少。这符合我的期望:array_values()似乎正在制作数组的副本,而array_splice就位。 - Doug Kavendek
当您在循环中删除元素并希望索引保持一致时,array_values是一种有用的方法,但是在循环之后需要将它们压缩出来。 - Rorrik


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

321
2017-11-15 11:29





$key = array_search($needle,$array);
if($key!==false){
    unset($array[$key]);
}

176
2017-12-15 20:31



最好澄清一下这个答案是为了删除元素,当你知道价值而不是关键时。请注意,它只删除值的FIRST实例;找到 所有 值的关键,使用 array_keys - ToolmakerSteve


unset($array[$index]);

58
2017-11-26 08:25





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


55
2017-07-31 01:06





此外,对于命名元素:

unset($array["elementName"]);


48
2017-07-19 15:37



$a = array("A"=>1, "B"=>2, "C"=>"a");  print_r($a);  unset($a["B"]);  print_r($a);  给(格式化): Array ( [A] => 1 [B] => 2 [C] => a ), Array ( [A] => 1 [C] => a ) - DefenestrationDay
看来你不能取消设置由字符串索引的数组元素(生成“致命错误:无法取消设置字符串偏移”)。我不认为情况总是如此,但从PHP 5.3.10开始,可能更早 - carpii
@carpii PHP可以从关联数组中取消设置元素。当您尝试在字符串而不是数组上使用unset($ var ['key'])时会导致致命错误例如:$ array = array('test'=>'value','another'=>'价值',);未设置($阵列[ '测试']); //按预期从数组中删除“test”元素$ array ='test';未设置($阵列[ '测试']); //按预期抛出“致命错误:无法取消设置字符串偏移” - Jimbo


销毁数组的单个元素

unset()

$array1 = array('A', 'B', 'C', 'D', 'E');
unset($array1[2]); // Delete known index(2) value from array
var_dump($array1);

输出将是:

array(4) {
  [0]=>
  string(1) "A"
  [1]=>
  string(1) "B"
  [3]=>
  string(1) "D"
  [4]=>
  string(1) "E"
}

如果需要重新索引数组:

$array1 = array_values($array1);
var_dump($array1);

然后输出将是:

array(4) {
  [0]=>
  string(1) "A"
  [1]=>
  string(1) "B"
  [2]=>
  string(1) "D"
  [3]=>
  string(1) "E"
}

从数组末尾弹出元素  - 返回已删除元素的值

mixed array_pop(array &$array)

$stack = array("orange", "banana", "apple", "raspberry");
$last_fruit = array_pop($stack);
print_r($stack);
print_r('Last Fruit:'.$last_fruit); // Last element of the array

输出将是

Array
(
    [0] => orange
    [1] => banana
    [2] => apple
)
Last Fruit: raspberry

从数组中删除第一个元素(红色), - 返回已删除元素的值

mixed array_shift ( array &$array )

$color = array("a" => "red", "b" => "green" , "c" => "blue");
$first_color = array_shift($color);
print_r ($color);
print_r ('First Color: '.$first_color);

输出将是:

Array
(
    [b] => green
    [c] => blue
)
First Color: red

26
2018-06-11 05:51





<?php
    $stack = array("fruit1", "fruit2", "fruit3", "fruit4");
    $fruit = array_shift($stack);
    print_r($stack);

    echo $fruit;
?>

输出:

Array
(
    [0] => fruit2
    [1] => fruit3
    [2] => fruit4
)

fruit1

22
2017-09-22 04:01



注意 array_shift 只能删除数组中的第一个元素。同样使用 array_pop 删除数组中的最后一个元素。 - Jasir
答案仅适用于数组的第一个元素,不能回答一般问题。 - sweisgerber.dev
@sebweisgerber你是对的,但我不认为这是错误的,需要对此问题进行投票。问题是删除一个元素,不提任何职位。 - Saurabh Chandra Patel


为了避免进行搜索,可以使用 array_diff

$array = array(3, 9, 11, 20);
$array = array_diff($array, array(11) ); // removes 11

在这种情况下,不必搜索/使用密钥。


20
2017-07-26 20:11





unset() 销毁指定的变量。

的行为 unset() 函数内部可能会有所不同,具体取决于您尝试销毁的变量类型。

如果全球化变量是 unset() 在函数内部,只破坏局部变量。调用环境中的变量将保留与之前相同的值 unset() 被称为。

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

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

上面代码的答案将是 酒吧

unset() 函数内部的全局变量

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

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

13
2018-03-11 18:48