在 PHP 中从数组中删除元素

Deleting an element from an array in PHP

提问人:Ben 提问时间:12/16/2008 最后编辑:StarBen 更新时间:11/17/2023 访问量:3706101

问:

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

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

PHP 数组未 设置

评论

17赞 brandizzi 7/27/2012
我不认为康拉德的答案是上述问题最简单的答案。通过迭代,数组将不再包含已删除的值。OTOH,Stevan 的答案确实很充分,实际上,这是我正在寻找的答案——但不是 OP :)unset()
48赞 Dan Nissenbaum 2/11/2014
@danip 在手册中很容易找到并不排除有关 StackOverflow 的问题。如果该问题是重复的 StackOverflow 问题,那么它可能不属于此处。StackOverflow 是一个寻找答案的好地方,甚至在查看手册之前,它就是一个首选选项。
7赞 trojan 9/4/2014
@unset($array[$key]);$array = array_values($array);
2赞 Somnath Muluk 12/26/2017
如果要从数组的数组(关联数组)中删除键,请参阅 stackoverflow.com/a/47978980/1045444 中的解决方案
3赞 blakroku 11/20/2019
将数组键值设置为 null 简单意味着包括具有 null 值的键。密钥仍然存在。

答:

3575赞 22 revs, 14 users 23%Rizier123 #1

有多种方法可以删除数组元素,其中一些方法对某些特定任务比其他方法更有用。

删除单个数组元素

如果你只想删除一个数组元素,你可以使用 unset()array_splice()。

按键还是按值?

如果您知道该值,但不知道删除元素的键,则可以使用 array_search() 来获取该键。 仅当元素出现不止一次时,这才有效,因为仅返回第一次命中。array_search()

unset()表达

注意:使用数组键时不会更改。 如果要重新索引键,可以在 、 之后使用 array_values() 这会将所有键转换为从 0 开始的数字枚举键 (数组仍然是一个列表)。unset()unset()

示例代码:

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

输出示例:

[
    [0] => a
    [2] => c
]

array_splice()功能

如果您使用(整数)键将自动重新索引, 但是关联(字符串)键不会改变——而不是 之后 , 这会将所有键转换为数字键。array_splice()array_values()unset()

注意:需要偏移量,而不是,作为第二个参数;offset 数组array_splice()= array_flip(array_keys())[]

示例代码:

$array = [0 => "a", 1 => "b", 2 => "c"];
array_splice($array, 1, 1);
                  // ↑ Offset of element to delete

输出示例:

[
    [0] => a
    [1] => c
]

array_splice(),与 相同,通过引用获取数组。不要将返回值赋回数组。unset()

删除多个数组元素

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

array_diff()功能

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

示例代码:

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

输出示例:

[
    [1] => b
]

array_diff_key()功能

如果您知道要删除的元素的键,则要使用 . 您必须确保在第二个参数中将键作为键传递,而不是作为值传递。 密钥不会重新编制索引。array_diff_key()

示例代码:

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

输出示例:

[
    [1] => b
]

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

array_filter()功能

如果要删除数组中具有特定值的所有元素,可以使用 .array_filter()

示例代码:

$array = [0 => "a", 1 => "b", 2 => "c"];
$array = array_filter($array, static function ($element) {
    return $element !== "b";
    //                   ↑
    // Array value which you want to delete
});

输出示例:

[
    [0] => a
    [2] => c
]

评论

31赞 Konrad Rudolph 6/13/2012
@AlexandruRada 不,你说“不要用这个”——那简直是无稽之谈。当您将数组视为字典时,您可以安全地使用此方法。只有当您需要连续的数字索引时,才需要使用其他东西。
9赞 Константин Ван 4/14/2017
unset可以有多个参数:.void unset ( mixed $var [, mixed $... ] )
4赞 dotnetCarpenter 5/6/2017
array_filter也是一种可行的方法。如果您不想改变数组,但也不会重新索引,这可能是json_encode的问题,这尤其好。php.net/manual/en/function.json-encode.php#94157
2赞 hvertous 12/3/2019
unset不是一个函数,而是一个语言结构(和一个关键字)。它不能也不能以“”为前缀
4赞 Clonkex 11/9/2022
为什么有反斜杠?对于任何不知道含义的人来说,这只会令人困惑,而对于任何知道的人来说,他们都会知道他们是否需要它们。完全不必要的IMO。
109赞 Eran Galperin 12/16/2008 #2
unset($array[$index]);
1423赞 Stefan Gehrig 12/16/2008 #3

应该注意的是,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()。另一种选择是在 unset() 之后使用 array_values():

$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)
} */

评论

51赞 Tom 6/9/2012
值得注意的是,当你使用 array_splice() 时,你需要知道 OFFSET,而不是键,而是你希望删除的任何元素的偏移量 (!)
20赞 Stefan Gehrig 6/9/2012
@Tom:对于常规数组(连续整数索引),偏移量是索引。这就是有意义的地方(除其他外)。array_splice
5赞 Tom 6/10/2012
当然可以,但如果您在使用拼接之前篡改阵列,请记住一些事情
4赞 Doug Kavendek 12/2/2014
从从一个巨大的数组中删除大量元素的基本测试来看,array_splice似乎更快,占用的内存更少。这与我的预期相符:array_values() 似乎正在复制数组,而array_splice在原地工作。
4赞 Rorrik 6/3/2015
当您删除循环中的元素并希望索引保持一致,但又希望在循环后将其压缩出来时,array_values是一种有用的方法。
77赞 DefenestrationDay 7/31/2010 #4

此外,对于命名元素:

unset($array["elementName"]);

评论

0赞 DefenestrationDay 6/9/2011
$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 )
0赞 carpii 4/6/2012
似乎您无法取消设置由字符串索引的数组元素(生成“致命错误:无法取消设置字符串偏移量”)。我不认为情况总是如此,但肯定是从 PHP 5.3.10 开始的,甚至可能更早
7赞 Jimbo 3/20/2013
@carpii PHP 可以从关联数组中取消设置元素。当您尝试在字符串而不是数组上使用 unset($var['key']) 时,会导致致命错误 例如: $array = array( 'test' => 'value', 'another' => 'value', );unset($array['测试']);按预期从数组中删除 “test” 元素 $array = 'test';unset($array['测试']);按预期抛出“致命错误:无法取消设置字符串偏移量”
0赞 Nabi K.A.Z. 10/16/2018
这里要知道密钥名称,比较好:stackoverflow.com/a/52826684/1407491
0赞 mickmackusa 8/23/2021
@Eran早在2008年就已经推荐了!如果你想改进这个建议,你应该编辑这个答案。这个多标签页上有太多冗余内容!unset()
426赞 Marcel Cozma 8/2/2011 #5
  // 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
)

评论

0赞 heart hacker 9/20/2018
$get_merged_values = array_merge($data['res'],$data['check_res']);当我打印此print_r时($get_merged_values);它显示以下内容。数组 ( [0] => 数组 ( [menu_code] => 2 [menu_name] => 植物 [menu_order_no] => 1 ) [1] => 数组 ( [menu_code] => 3 [menu_name] => 行 [menu_order_no] => 2 ) ) 但是我需要分别使用 $get_merged_values['menu_code'] 和 $get_merged_values['menu_name'] 来获取 menu_code 和 menu_name 的值, 而不是使用 $get_merged_values[0][menu_code],而是$get_merged_values[0][menu_name]。请帮我怎么做?
0赞 Jed Lynch 10/13/2020
这个问题的措辞从它的陈述方式上具有误导性。如果要删除 foreach 循环中的 $arr[$i],如果多个元素具有相同的值,这将不起作用。
1赞 Mohammed Sufian 8/19/2022
array_merge(array_diff(你节省了我的时间,谢谢你的两个例子,以及1.keys are not re-indexedanother one with keys are indexed again from 0...n
242赞 liamvictor 11/15/2011 #6
$key = array_search($needle, $array);
if ($key !== false) {
    unset($array[$key]);
}

评论

9赞 ToolmakerSteve 9/25/2016
最好澄清一下,这个答案是用于删除元素的,当你知道值,但不知道键。请注意,它只删除值的第一个实例;若要查找某个值的所有键,请使用 array_keys
0赞 Jed Lynch 10/13/2020
如果多个元素具有相同的值,则此操作将不起作用。
75赞 Robin Nixon 11/26/2012 #7

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

评论

0赞 Jed Lynch 10/13/2020
如果两个元素具有相同的值,则此操作将不起作用。
6赞 4 revs, 4 users 30%Jens Erat #8

使用以下代码:

$arr = array('orange', 'banana', 'apple', 'raspberry');
$result = array_pop($arr);
print_r($result);

评论

5赞 Krista K 9/16/2014
php5:只需运行即可删除最后一个条目。不需要 ' = '。array_pop($arr)
39赞 Saurabh Chandra Patel 6/11/2013 #9
<?php
    $stack = ["fruit1", "fruit2", "fruit3", "fruit4"];
    $fruit = array_shift($stack);
    print_r($stack);

    echo $fruit;
?>

输出:

[
    [0] => fruit2
    [1] => fruit3
    [2] => fruit4
]

fruit1

评论

16赞 Jasir 7/23/2014
请注意,只能删除数组中的第一个元素。类似地用于删除数组中的最后一个元素。array_shiftarray_pop
3赞 sweisgerber.dev 10/14/2014
答案仅适用于数组的第一个元素,不回答一般问题。
0赞 Saurabh Chandra Patel 10/14/2014
@sebweisgerber你是对的,但我不认为这是错的,需要投反对票。问题是删除一个元素,不提及任何位置。
1赞 Jed Lynch 10/13/2020
这仅涵盖一种边缘情况
0赞 mickmackusa 8/23/2021
如前所述,这种技术没有很高的实用性。这个答案缺少其教育解释。
22赞 Ankit Aggarwal 7/27/2013 #10

unset()销毁指定的变量。

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

如果全局变量位于函数内部,则仅销毁局部变量。调用环境中的变量将保留与调用之前相同的值。unset()unset()

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

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

上面代码的答案将是 bar

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

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

    $bar = "something";
    foo();
?>
11赞 Oxydel 8/21/2013 #11

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

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

40赞 KTAnj 7/19/2015 #12

销毁数组的单个元素

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

评论

1赞 Nabi K.A.Z. 10/16/2018
如果键项是整数,则重新索引,所以它很糟糕,所以你可以使用这个: stackoverflow.com/a/52826684/1407491array_shift
0赞 AmigoJack 10/23/2021
array_shift() 的复杂度为 O(n)(由于重新索引数字索引),而 array_pop() 的复杂度为 O(1)。如何了解第一个元素的索引?只需在第一次迭代中启动一个即可。foreachbreak
14赞 msvairam 1/25/2016 #13

遵循默认功能:

  • PHP:未设置

unset()销毁指定的变量。更多信息可以参考 PHP unset

$Array = array("test1", "test2", "test3", "test3");

unset($Array[2]);
  • PHP:array_pop

该函数删除数组的最后一个元素。更多信息,可以参考 PHP array_poparray_pop()

$Array = array("test1", "test2", "test3", "test3");

array_pop($Array);
  • PHP:array_splice

该函数从数组中删除选定的元素,并将其替换为新元素。更多信息,可以参考 PHP array_splicearray_splice()

$Array = array("test1", "test2", "test3", "test3");

array_splice($Array,1,2);
  • PHP:array_shift

该函数从数组中删除第一个元素。更多信息,可以参考 PHP array_shiftarray_shift()

$Array = array("test1", "test2", "test3", "test3");

array_shift($Array);
30赞 spyle 2/18/2016 #14

如果您必须删除数组中的多个值,并且该数组中的条目是对象或结构化数据,则 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']]
23赞 John Slegers 3/12/2016 #15

关联数组

对于关联数组,请使用 unset

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

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

数值数组

对于数值数组,请使用array_splice

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

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

注意

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

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

// RESULT: array(0 => 1, 2 => 3)
20赞 Gigoland 4/3/2016 #16
// Remove by value
function removeFromArr($arr, $val)
{
    unset($arr[array_search($val, $arr)]);
    return array_values($arr);
}

评论

0赞 mickmackusa 8/22/2021
这个纯代码答案并不稳定。如果 未找到目标值,则其返回值将有效地删除非预期且会损坏输入数据的键控元素。我会敦促研究人员不要使用这个片段。array_search()false[0]
26赞 Simon 4/21/2016 #17

如果需要从关联数组中删除多个元素,可以使用 array_diff_key()(此处与 array_flip() 一起使用):

$my_array = array(
  "key1" => "value 1",
  "key2" => "value 2",
  "key3" => "value 3",
  "key4" => "value 4",
  "key5" => "value 5",
);

$to_remove = array("key2", "key4");

$result = array_diff_key($my_array, array_flip($to_remove));

print_r($result);

输出:

Array ( [key1] => value 1 [key3] => value 3 [key5] => value 5 ) 

评论

0赞 Fr0zenFyr 12/2/2016
为什么这被低估了?
1赞 mickmackusa 8/22/2021
因为研究人员正在努力消费一个过度臃肿的页面,其中包含冗余的答案。在这个规范的页面上,“研究人员体验”被严重破坏了。
7赞 Umar Farooque Khan 8/16/2016 #18
<?php
    // If you want to remove a particular array element use this method
    $my_array = array("key1"=>"value 1", "key2"=>"value 2", "key3"=>"value 3");

    print_r($my_array);
    if (array_key_exists("key1", $my_array)) {
        unset($my_array['key1']);
        print_r($my_array);
    }
    else {
        echo "Key does not exist";
    }
?>

<?php
    //To remove first array element
    $my_array = array("key1"=>"value 1", "key2"=>"value 2", "key3"=>"value 3");
    print_r($my_array);
    $new_array = array_slice($my_array, 1);
    print_r($new_array);
?>


<?php
    echo "<br/>    ";
    // To remove first array element to length
    // starts from first and remove two element
    $my_array = array("key1"=>"value 1", "key2"=>"value 2", "key3"=>"value 3");
    print_r($my_array);
    $new_array = array_slice($my_array, 1, 2);
    print_r($new_array);
?>

输出

 Array ( [key1] => value 1 [key2] => value 2 [key3] =>
 value 3 ) Array (    [key2] => value 2 [key3] => value 3 )
 Array ( [key1] => value 1 [key2] => value 2 [key3] => value 3 )
 Array ( [key2] => value 2 [key3] => value 3 )
 Array ( [key1] => value 1 [key2] => value 2 [key3] => value 3 )
 Array ( [key2] => value 2 [key3] => value 3 )

评论

0赞 mickmackusa 8/22/2021
在调用 之前检查密钥是否存在是没有好处的。如果在数组中找不到密钥,则将静默地执行任何操作(如预期的那样)。 并且在此答案发布之前已经被推荐。此答案不会为此页面添加任何新值。unset()unset()unset()array_slice()
7赞 MahdiY 9/22/2017 #19

删除基于键的数组元素:

使用如下函数:unset

$a = array(
       'salam',
       '10',
       1
);

unset($a[1]);

print_r($a);

/*

    Output:

        Array
        (
            [0] => salam
            [2] => 1
        )

*/

根据值删除数组元素:

使用函数获取元素键,并使用上述方式删除数组元素,如下所示:array_search

$a = array(
       'salam',
       '10',
       1
);

$key = array_search(10, $a);

if ($key !== false) {
    unset($a[$key]);
}

print_r($a);

/*

    Output:

        Array
        (
            [0] => salam
            [2] => 1
        )

*/

评论

1赞 mickmackusa 8/22/2021
unset()并在 2017 年发布。这个答案只是提供了多余的见解。array_search()unset()
8赞 Kristoffer Bohmann 12/7/2017 #20

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() 不接受要删除的键数组,因此下面的代码将失败(不过,动态使用 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 ]

通过复制数组删除数组键

还有另一种做法尚未提及。 有时,摆脱某些数组键的最简单方法是简单地将 $array 1 复制到 $array 2 中。

$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' ]
16赞 Star 1/29/2018 #21

解决 方案:

  1. 要删除一个元素,请使用 unset():
unset($array[3]);
unset($array['foo']);
  1. 要删除多个不连续的元素,还可以使用 unset()
unset($array[3], $array[5]);
unset($array['foo'], $array['bar']);
  1. 要删除多个连续元素,请使用 array_splice()
array_splice($array, $offset, $length);

进一步说明:

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

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

除了语法之外,使用 unset() 和将 '' 赋值给元素之间还有逻辑上的区别。第一个说,而第二个说This doesn't exist anymore,This still exists, but its value is the empty string.

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

unset($products['XL1000']);

但是,如果它暂时用完了 XL1000 链轮,但计划在本周晚些时候从工厂接收新货物,那就更好了:

$products['XL1000'] = 0;

如果你 unset() 一个元素,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()。

10赞 Nabi K.A.Z. 10/16/2018 #22

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

解决方案#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"
}

评论

3赞 mickmackusa 8/22/2021
array_slice()并且在您发布答案之前已经多次演示。这个答案是多余的,只会损害研究人员的体验。unset()
1赞 Nabi K.A.Z. 8/23/2021
@mickmackusa但我的回答是干净明了的。
1赞 mickmackusa 8/23/2021
...和冗余。您尚未向此页面添加任何特定于元素删除的唯一值。你已经偏离了主题,谈论如何定位第一个元素的键。OP 没有提到想要针对第一个元素。通过阅读这个非常拥挤的页面中的其他答案,您可能被骗入了不同的范围。为了改善研究人员的体验,可以安全地删除此答案。
32赞 Ahmad Mobaraki 5/23/2019 #23

如果指定了索引:

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

如果我们有 value 而不是 index:

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

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

评论

1赞 mickmackusa 8/22/2021
unset()几年前已经多次在此页面上推荐。 早在 2011 年就被证明了这一点。stackoverflow.com/a/8135667/2943403此答案不会向此页面添加任何新值。array_search()unset()
0赞 Ahmad Mobaraki 8/22/2021
@mickmackusa也许你是对的,这个答案中的所有信息都可以在其他不同的答案中找到。但是,也许在不同条件下将所有答案都放在一个答案中并简单解释,可以为某人节省一些时间。所以我想它可以被认为是价值!
0赞 mickmackusa 8/22/2021
这是看待它的一种方式。查看此多标签页面的另一种方式是“因冗余建议而严重过度膨胀”。研究人员一遍又一遍地浏览相同的建议,以确保他们正在考虑所有相关建议。因为答案是单一和多种技术的混合体,而且许多答案都在说同样的事情——研究人员的体验受到了很大的损害。想象一下,如果您需要此页面的建议。你想读一本充满多余建议的小说吗?我不会。
0赞 mickmackusa 8/22/2021
如果您个人认为以前的答案“不清楚”或需要更多详细信息,您可以编辑这些答案以更好地帮助研究人员,而不是发布新答案。这意味着更好的建议分布在更少的总答案中。
1赞 oyvey 6/11/2023
我发现艾哈迈德的回答很有帮助。
9赞 Sam Tigle 6/11/2019 #24

编辑

如果你不能认为对象在该数组中,你需要添加一个检查:

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"
    }
}

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

评论

0赞 mickmackusa 8/22/2021
这个答案并不稳定。如果未找到目标数组键,则其返回值将有效地销毁键控元素。此代码段很危险,应将其删除。早期的答案没有犯这个错误。array_search()[0]
0赞 Sam Tigle 8/24/2021
@mickmackusa感谢您的提示,添加了一个检查
0赞 mickmackusa 8/24/2021
对阵列进行一次潜在的完全扫描,然后再次进行另一次潜在的完全扫描,这绝对不是我建议任何人做的事情。这简直是不好的做法。我的立场仍然是——这个答案犯了以前答案没有犯的错误。更正此答案只会使它与先前的答案多余。如果删除此答案,此页面将得到改进。in_array()array_search()
2赞 Jed Lynch 10/13/2020 #25

我来这里是因为我想看看是否有比使用 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'];
0赞 Syed Kazim Ali Shah 11/11/2023 #26

要从 PHP 中的数组中删除元素,使其不再包含在循环中,您可以使用多种方法。下面是一个简单的方法:foreach

方法:使用unset()

  • 用法:非常适合在知道元素键时删除元素。
  • 行为:不重新索引数字数组键。
  • 示例
    $myArray = ['apple', 'banana', 'cherry'];
    unset($myArray[1]); // Removes 'banana'
    

方法:使用array_splice()

  • 用法:当您想要根据元素的位置(偏移量)删除元素并自动重新索引数字键时,这很有用。
  • 示例
    $myArray = ['apple', 'banana', 'cherry'];
    array_splice($myArray, 1, 1); // Removes 'banana'
    

方法:使用array_diff()

  • 用法:适用于按值删除元素。不影响按键。
  • 示例
    $myArray = ['apple', 'banana', 'cherry'];
    $myArray = array_diff($myArray, ['banana']); // Removes 'banana'
    

方法:使用array_filter()

  • 用法:最适合根据条件删除元素。
  • 示例
    $myArray = ['apple', 'banana', 'cherry'];
    $myArray = array_filter($myArray, function($item) {
        return $item !== 'banana';
    });
    

这些方法中的每一种都有其特定的用例和对数组结构的影响,尤其是在键方面。选择最适合您需求的一款。

有关 PHP 中数组操作的更全面的见解和高级示例,您可能会发现本文很有帮助。

0赞 svrl 11/15/2023 #27

正如你所说,你可以将精确索引的元素设置为null,但随后你必须这样做,例如array_filter(),它删除了所有的null和false值(重复的值将保留) - 考虑下面的示例和结果:

$testArray = 
[
    'asd',
    'asd',
    null,
    false,
    true,
    123,
    456,
    123
];

print_r(array_filter($testArray));

# Result    
Array
(
    [0] => asd
    [1] => asd
    [4] => 1
    [5] => 123
    [6] => 456
    [7] => 123
)

另一种方法当然是 unset() 函数,其用法可能如下所示:

unset($testArray[1]) for example


$testArray = 
[
    'asd',
    true,
    456,
    123
];

unset($testArray[1]);

print_r($testArray);

# Result
Array
(
    [0] => asd
    [2] => 456
    [3] => 123
)

从数组中删除元素的下一个方法是 array_splice() 函数,您可以定义数组、起始位置和要删除的索引数 - 考虑下面的 PHP:

$testArray = 
[
    'asd',
    true,
    456,
    123
];

array_splice($testArray, 0, 1);

print_r($testArray);

# Result
Array
(
    [0] => 1
    [1] => 456
    [2] => 123
)

从数组中删除元素的另一种不太简单的方法:

  • array_diff() 将一个数组与另一个数组区分开来,从而通过过滤器数组改变第一个数组
  • array_shift() 删除数组的第一个元素
  • array_pop() 删除数组的最后一个元素
  • array_intersect() 过滤掉两个数组的交集,从而通过主数组(第一个参数)生成包含所有通用值的数组

评论

0赞 DarkBee 11/15/2023
这个答案除了已经存在的答案之外没有增加任何新的东西......