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

196

当我知道数组中某个元素的值时,如何从数组中删除该元素?例如:

我有一个数组:

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

用户输入strawberry

$array中删除strawberry

完整解释:

我有一个数据库,它存储以逗号分隔的项目列表。代码基于用户选择的位置来提取列表。例如,如果他们选择了草莓,代码会提取出每个包含草莓的条目,然后使用split()将其转换为数组。我想要从数组中删除用户选择的物品(本例中为草莓)。


4
同样的问题:https://dev59.com/EGw05IYBdhLWcg3weBpF - trante
1
另一个相同的问题:https://dev59.com/WHI-5IYBdhLWcg3wYnSQ - Eric Lavoie
1
更多相同的问题:https://dev59.com/pnRC5IYBdhLWcg3wOeWB - Alex
22个回答

360

使用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]);
}

1
得到了一个奇怪的结果。我使用了你的第一个建议,因为总会只有一个实例。为了测试它,我只是让它输出键值。有效。然而,它无法取消设置。 - dcp3450
1
当(odbc_fetch_row($runqueryGetSubmenus))时 { $submenuList = odbc_result($runqueryGetSubmenus,"submenus"); $submenuArray = split(',',$submenuList); if (($key = array_search($name,$submenuArray)) !== false) { unset($submenuArray[$key]); } } - dcp3450
@dcp3450:你对$submenuArray做什么?(请注意,每次循环$submenuArray都会被覆盖。) - Gumbo
我更新了我的问题以更好地解释。基本上,该代码循环遍历数据库中的条目,删除所选项目,例如此处的“草莓”。因此,用户输入选择=>代码在子菜单下搜索并找到具有该选项的任何列表=>将该列表转换为数组=>删除所选选项。 - dcp3450
1
我明白了!我没有将新数组重新写回数据库。当你盯着代码看很长时间时,很容易错过这些细节。 - dcp3450
显示剩余2条评论

187

使用 array_diff() 可以得到一行代码的解决方案:

$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循环。


11
这个解决方案比前面的更易读。 - Robbert
10
你的说法是错误的。$a = array_diff(array(), array('strawberry')); - $a 是一个空数组。 - bancer
2
你是对的@bancer - 我可能在想array_intersect或其他东西。 - Erfan
2
array_diff()比标记答案更优雅。 - Dom DaFonte
1
@robsch 是的。unset()函数也是这样做的,只是取消一个元素。 - Alexis Wilke
显示剩余2条评论

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

2
你应该测试数组中是否包含strawberry - Gumbo
按照 Gumbo 的建议,修改了答案以在从数组中删除元素之前验证该元素。 - John Conde
2
请注意,在删除特定元素后,索引不会重新对齐。换句话说,索引序列将会有间隙。如果您从示例中删除“草莓”,则“猕猴桃”仍将具有索引4,而索引2将消失。如果您的代码依赖于索引序列的完整性,例如for($i = 0; $i <.., $i++)循环,则这很重要。 - the-banana-king
2
补充一下the-banana-king所说的,如果你想重新索引数组,只需执行$my_array = array_values($my_array);即可。 - ryeguy
2
虽然这个解决方案是正确的,但它会搜索两次数组(in_arrayarray_search)。使用Gumbo答案中的array_search返回值更有效。 - Bogdan D

28

如果您在这里使用的是普通数组(似乎是这种情况),则应改用以下代码:

if (($key = array_search('strawberry', $array)) !== false) {
    array_splice($array, $key, 1);
}
< p > 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

28
你可以使用一行代码来完成,这会将元素从数组中删除。
$array = array_diff($array,['strawberry']);

1
这应该是被接受的答案,因为unset在数组中留下了一个“空洞”。 - Csongor Fagyal
也许吧,但代码应该简单...KISS原则 - dılo sürücü

15
你可以使用数组过滤器,根据$v的特定条件来删除项目:

你可以使用数组过滤器,根据$v的特定条件来删除项目:

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

1
Downvote。这个低质量的答案(因为它只是一个代码答案,而且会导致解析错误)是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");

3

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

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

3

使用这种简单的方式,希望能够有所帮助。

foreach($array as $k => $value)
    {
      
        if($value == 'strawberry')
        {
          unset($array[$k]);
        }
    }

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

因此,最终的数组不会重新索引。因此,在 unsetarray_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

与这篇文章相关的链接:重新索引数组

enter image description here

希望它能有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接