PHP:如何从数组中删除特定元素?


159

当我知道元素名称时,如何从数组中删除元素?例如:

我有一个数组:

$array = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');

用户输入 strawberry

strawberry 已移除。

要充分说明:

我有一个数据库,该数据库存储用逗号分隔的项目列表。该代码根据用户选择所在的位置来提取列表。因此,如果他们选择草莓,则会在草莓所在的每个条目中进行代码提取,然后使用split()将其转换为数组。我想让他们从数组中删除用户选择的项目,例如此示例草莓。




Answers:


295

使用array_search拿到钥匙,并删除它unset一旦发现:

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

array_search如果未找到任何项目,则返回false(直到PHP 4.2.0为止为null)。

而且,如果可以有多个具有相同值的项目,则可以array_keys用来获取所有项目的键:

foreach (array_keys($array, 'strawberry') as $key) {
    unset($array[$key]);
}

得到一个奇怪的结果。我使用了您的第一个建议,因为总是只有一个实例。为了测试它,我只是让它输出键值。工作了 但是,它不会设置。
— dcp3450 2010年

1
while(odbc_fetch_row($ runqueryGetSubmenus)){$ submenuList = odbc_result($ runqueryGetSubmenus,“ submenus”); $ submenuArray = split(',',$ submenuList); 如果(($ key = array_search($ name,$ submenuArray))!== false){unset($ submenuArray [$ key]); }}
— dcp3450

@ dcp3450:那你怎么办$submenuArray?(请注意,每个循环$submenuArray都会被覆盖。)
— Gumbo 2010年

我更新了我的问题以更好地解释。基本上,代码循环遍历数据库中的条目,以删除所选项目,在此示例中为“草莓”。因此,用户输入一个选择=>代码将在子菜单下搜索,并找到具有该选项的任何列表=>将该列表转换为数组=>删除所选的选项。
— dcp3450 2010年

1
我知道了!我并没有将新阵列改写回数据库。当您凝视代码很长时间时,很容易错过东西。
— dcp3450 2010年

153

使用array_diff()1级的解决方案:

$array = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi', 'strawberry'); //throw in another 'strawberry' to demonstrate that it removes multiple instances of the string
$array_without_strawberries = array_diff($array, array('strawberry'));
print_r($array_without_strawberries);

...不需要额外的功能或foreach循环。


8
这种解决方案比顶级解决方案更清晰。
— 罗伯特

尽管if strawberry不在初始数组中,但是它将在$array_without_strawberries数组中变为可用-如果要确保给定元素不在数组中,则为危险代码。
— Erfan

5
@Erfan您的主张是错误的。$a = array_diff(array(), array('strawberry'));-$ a是一个空数组。
— bancer '17

1
你是对的@bancer-我可能在想array_intersect之类的东西。
— Erfan

1
array_diff()比标记的答案更优雅。
— Dom DaFonte

36
if (in_array('strawberry', $array)) 
{
    unset($array[array_search('strawberry',$array)]);
}

2
您应该测试草莓是否在阵列中。
— Gumbo 2010年

遵循Gumbo的建议,修改后的答案包括在从数组中删除元素之前对其进行验证。
— 约翰·孔德

2
还请记住,删除特定元素后,索引不会重新对齐。换句话说,索引序列将具有间隙。如果从示例中删除“草莓”,则“奇异果”仍将具有索引4,而索引2则将消失。重要的是您的代码是否依赖于索引序列的完整性,例如for($ i = 0; $ i <..,$ i ++)循环。
— 香蕉王

2
要补充香蕉王的话,如果您想为数组重新索引,只需执行即可$my_array = array_values($my_array);。
— ryeguy 2010年

2
尽管此解决方案正确,但它会搜索数组TWICE(in_array和array_search)。array_search在Gumbo的答案中使用as 的返回更有效
— Bogdan D

21

如果您在此处使用普通数组(看起来像是这种情况),则应改用以下代码:

if (($key = array_search('strawberry', $array)) !== false) {
    array_splice($array, $key, 1);
}

unset($array[$key]) 仅删除元素,但不重新排列普通数组。

假设我们有一个数组,并使用array_splice:

$array = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');
array_splice($array, 2, 1);
json_encode($array); 
// yields the array ['apple', 'orange', 'blueberry', 'kiwi']

与未设置的相比:

$array = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');
unset($array[2]);
json_encode($array);
// yields an object {"0": "apple", "1": "orange", "3": "blueberry", "4": "kiwi"}

注意如何unset($array[$key])不重新排列数组。


正式unset不返回任何东西。因此json_encode(unset($array[2]))不适合进行比较。
— robsch

这正是我所需要的,谢谢ericluwj
— ana

12

您可以使用数组过滤器按以下特定条件删除项目$v:

$arr = array_filter($arr, function($v){
    return $v != 'some_value';
});

下注。这种低质量的(因为它是仅代码的答案,并且给出了解析错误)是D.Martin方法的复制品,该方法仅在内部使用匿名函数array_filter()。虽然我个人将在实现中使用匿名函数,但我相信对SO的正确操作是,如果您希望进行微改进,则对D.Martin的答案进行评论或编辑,以使该页面不会显得肿。请删除此重复的答案。
— mickmackusa

4

将是这样的:

 function rmv_val($var)
 {
     return(!($var == 'strawberry'));
 }

 $array = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');

 $array_res = array_filter($array, "rmv_val");

4

这是一个简单的重复操作,可以删除数组中的多个值。

    // Your array
    $list = array("apple", "orange", "strawberry", "lemon", "banana");

    // Initilize what to delete
    $delete_val = array("orange", "lemon", "banana");

    // Search for the array key and unset   
    foreach($delete_val as $key){
        $keyToDelete = array_search($key, $list);
        unset($list[$keyToDelete]);
    }

对于PHP开发人员已经在中创建的内容,这是一种低效的本地化替代方法array_diff()。这是如何获得三个赞誉的。没有人会发现这个答案有帮助或在自己的项目中使用它。我建议删除此答案-这样可以使您的帐户摆脱低质量答案的困扰,减少此页面上的答案膨胀,并为您赢得纪律勋章。我会推迟投票,以便您有时间删除以获得奖励。
— mickmackusa

4

只是你可以做单行。它将从数组中删除元素


$array=array_diff($array,['strawberry']);


3

我目前正在使用此功能:

function array_delete($del_val, $array) {
    if(is_array($del_val)) {
         foreach ($del_val as $del_key => $del_value) {
            foreach ($array as $key => $value){
                if ($value == $del_value) {
                    unset($array[$key]);
                }
            }
        }
    } else {
        foreach ($array as $key => $value){
            if ($value == $del_val) {
                unset($array[$key]);
            }
        }
    }
    return array_values($array);
}

您可以输入一个数组或仅包含要删除元素的字符串。这样写:

$detils = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');
$detils = array_delete(array('orange', 'apple'), $detils);

要么

$detils = array_delete('orange', $detils);

它还会重新编制索引。


2
这是令人费解的和混乱的。这是如何获得3次投票的?!
— mickmackusa

2

这个问题有几个答案,但是我想添加更多的内容,因为当我使用unset或array_diff删除特定元素时(因为保存了初始索引),在处理新数组的索引时遇到了一些问题。

我回到例子:

$array = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');
$array_without_strawberries = array_diff($array, array('strawberry'));

要么

$array = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');
unset($array[array_search('strawberry', $array)]);

如果打印结果,您将获得:

foreach ($array_without_strawberries as $data) {
   print_r($data);
}

结果:

> apple
> orange
> blueberry
> kiwi

但是索引将被保存,因此您将可以像这样访问元素:

$array_without_strawberries[0] > apple
$array_without_strawberries[1] > orange
$array_without_strawberries[3] > blueberry
$array_without_strawberries[4] > kiwi

因此,最终数组不会重新索引。因此,您需要在unset或之后添加array_diff:

$array_without_strawberries = array_values($array);

之后,您的数组将具有正常索引:

$array_without_strawberries[0] > apple
$array_without_strawberries[1] > orange
$array_without_strawberries[2] > blueberry
$array_without_strawberries[3] > kiwi

与此相关的帖子:重新索引数组

在此处输入图片说明

希望对你有帮助


1

更好的方法可能是将值作为键保留在关联数组中,然后array_keys()在要实际数组时调用它。这样,您就无需使用它array_search来查找元素。


1
您的帖子是评论而不是答案。请删除并在问题本身下发布。
— mickmackusa

1

PHP数组按值(不是键)删除的答案, 由 https://stackoverflow.com/users/924109/rok-kralj提供

IMO是最好的答案,因为它可以去除并且不会变异

array_diff( [312, 401, 15, 401, 3], [401] ) // removing 401 returns [312, 15, 3]

它的概括很好,如果需要,您可以同时删除任意多个元素。

免责声明:请注意,我的解决方案会生成一个数组的新副本,同时与旧的答案保持一致,同时保持原来的副本不变。因此,它可能会慢一些。


1

我一直在寻找相同问题的答案,并遇到了这个话题。我看到两种主要方式:array_search&的组合unset和使用的array_diff。乍看起来,第一种方法会更快,因为它不需要创建其他数组(如使用时array_diff)。但是我写了一个小的基准,并确保第二种方法不仅更简洁,而且更快!很高兴与您分享。:)

https://glot.io/snippets/f6ow6biaol


0

我更喜欢使用array_key_exists在数组中搜索键,例如:

Array([0]=>'A',[1]=>'B',['key'=>'value'])

查找有效的指定,因为array_search和in_array()在这里不起作用。并使用unset()删除内容。

我认为这会帮助某人。


0

创建带有删除特定数组值的数字数组

    <?php
    // create a "numeric" array
    $animals = array('monitor', 'cpu', 'mouse', 'ram', 'wifi', 'usb', 'pendrive');

    //Normarl display
    print_r($animals);
    echo "<br/><br/>";

    //If splice the array
    //array_splice($animals, 2, 2);
    unset($animals[3]); // you can unset the particular value
    print_r($animals);

    ?>

您可以参考此链接。


下注。该问题明确要求删除基于值(而不是键)的值。这个答案没有用,请删除。
— mickmackusa

0
$remove= "strawberry";
$array = ["apple", "orange", "strawberry", "blueberry", "kiwi"];
foreach ($array as $key => $value) {
        if ($value!=$remove) {
        echo $value.'<br/>';
                continue;
        }
}

这个答案甚至没有删除所需的选项。
— Nigel Ren

-1

使用array_seach(),请尝试以下操作:

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

array_search()返回找到的元素的键,可使用将键从原始数组中删除该元素unset()。它将FALSE在失败时返回,但是在成功时可以返回“假”值(0例如,您的密钥),这就是为什么使用严格比较运算符的原因!==。

该if()语句将检查是否array_search()返回值,并且仅在返回值时才执行操作。


3
下注。这是Gumbo的方法(目前是公认的解决方案)的副本,该方法早于您的发布。重复的答案没有价值,只会造成不必要的页面膨胀。请删除您的答案。如果你想解释甘博的回答,对他的答案编辑这样做,或要求浓汤,扩大了自己的答案..
— mickmackusa

-1
unset($array[array_search('strawberry', $array)]);

2
下注。本array_search()- unset()方法已经由之前你孔德约翰张贴年前。重复的答案对读者毫无价值,实际上是不便的,因为在滚动和读取冗余信息时会浪费时间。请删除此答案。
— mickmackusa

-1
<?php 
$array = array("apple", "orange", "strawberry", "blueberry", "kiwi");
$delete = "strawberry";
$index = array_search($delete, $array);
array_splice($array, $index, 1);
var_dump($array);
?>

2
您可以通过写一两个句子来改善此答案:a)代码的作用,以及b)为什么您认为它是所有其他答案中的一个选择。
— 罗宾·麦肯齐


-2
$detils = array('apple', 'orange', 'strawberry', 'blueberry', 'kiwi');
     function remove_embpty($values)
     {
        if($values=='orange')
        {
            $values='any name';
        }
        return $values;
     }
     $detils=array_map('remove_embpty',$detils);
    print_r($detils);

2
还请添加说明。它如何解决问题。
— Rahil Wazir 2014年

您的答案将数组的一个元素替换为另一个NO以删除元素
— ahmed hamdy 2014年

下注。该答案未提供预期的输出。请删除此错误答案。
— mickmackusa
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.