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_arrayarray_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

这个问题有几个答案,但是我想添加更多的内容,因为当我使用unsetarray_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.