按值删除数组项


166

我需要删除具有给定值的数组项:

if (in_array($id, $items)) {
    $items = array_flip($items);
    unset($items[ $id ]);
    $items = array_flip($items);
}

可以用更短(更有效)的方式完成吗?


Answers:


423

只需一个简单的内衬即可完成。

具有此数组:

$arr = array('nice_item', 'remove_me', 'another_liked_item', 'remove_me_also');

你可以做:

$arr = array_diff($arr, array('remove_me', 'remove_me_also'));

的值为$arr

array('nice_item', 'another_liked_item')

希望它有助于编写漂亮的代码。


2
不,它确实适用于引用数组,该array_diff函数是非破坏性的,它返回一个新数组。
亚历杭德罗·加西亚·伊格莱西亚斯

2
@srcspider为什么不呢?$referenced = array_diff($referenced, $items_to_remove);
亚历杭德罗·加西亚·伊格莱西亚斯

1
$ referenced现在指向一个新数组,您要更改的数组仍然具有旧值。
srcspider

2
@srcspider好,你告诉我这是怎么回事... codepad.org/11ZhiFP0
亚历杭德罗·加西亚·伊格莱西亚斯

1
我的错; php的可变别名别名总是使我绊倒>。>
srcspider 2013年

37

我要添加第二个答案。我写了一个快速的基准测试脚本来尝试各种方法。

$arr = array(0 => 123456);
for($i = 1; $i < 500000; $i++) {
    $arr[$i] = rand(0,PHP_INT_MAX);
}

shuffle($arr);
$arr2 = $arr;
$arr3 = $arr;

/** 
 * Method 1 - array_search()
 */
$start = microtime(true);
while(($key = array_search(123456,$arr)) !== false) {
    unset($arr[$key]);
}
echo count($arr). ' left, in '.(microtime(true) - $start).' seconds<BR>';

/** 
 * Method 2 - basic loop
 */
$start = microtime(true);
foreach($arr2 as $k => $v) {
    if ($v == 123456) {
        unset($arr2[$k]);
    }
}
echo count($arr2). 'left, in '.(microtime(true) - $start).' seconds<BR>';

/** 
 * Method 3 - array_keys() with search parameter
 */
$start = microtime(true);
$keys = array_keys($arr3,123456);
foreach($keys as $k) {
    unset($arr3[$k]);
}
echo count($arr3). 'left, in '.(microtime(true) - $start).' seconds<BR>';

第三种方法,array_keys()指定了可选的搜索参数,似乎是最好的方法。输出示例:

499999 left, in 0.090957164764404 seconds
499999left, in 0.43156313896179 seconds
499999left, in 0.028877019882202 seconds

以此判断,我将使用的解决方案是:

$keysToRemove = array_keys($items,$id);
foreach($keysToRemove as $k) {
    unset($items[$k]);
}

我认为array_search比使用array_diff方法更具可读性。Upvote
kendepelchin

@zombat我想知道订单是否与结果有关。随机播放有可能使我们搜索的值更接近前端或后端。除此之外... +1
乡下人将军(

31

怎么样:

if (($key = array_search($id, $items)) !== false) unset($items[$key]);

或多个值:

while(($key = array_search($id, $items)) !== false) {
    unset($items[$key]);
}

这也将防止密钥丢失,这是的副作用array_flip()


1
如果$ id是第一个数组元素,将无法正常工作,更好的方式是:if((($ key = array_search($ id,$ items))!== false)unset($ items [$ key]);
Marek

15

除去$rm_val$arr

unset($arr[array_search($rm_val, $arr)]);

8

最强大的解决方案是使用array_filter,它允许您定义自己的过滤功能。

但是有些人可能会说,在您的情况下,这有点过头了……
一个简单的foreach循环遍历数组并删除不需要的项就足够了。

就您而言,类似这样的方法应该可以解决问题:

foreach ($items as $key => $value) {
    if ($value == $id) {
        unset($items[$key]);
        // If you know you only have one line to remove, you can decomment the next line, to stop looping
        //break;
    }
}

6

3
我刚刚阅读了文档,建议使用array_keys()查找与值关联的所有键。
Savageman

@Savageman-同意。我运行了一个快速基准测试,array_keys()似乎比array_search()此任务执行得更好。
zombat

6

仅当数组中具有唯一值时,您的解决方案才有效

看到:

<?php
$trans = array("a" => 1, "b" => 1, "c" => 2);
$trans = array_flip($trans);
print_r($trans);
?>

如果有必要,最好在循环中使用array_search取消设置更好的方法。


您是对的,但是在这种情况下,我非常确定值是唯一的:)
Marek

5

不翻转:

<?php
foreach ($items as $key => $value) {
    if ($id === $value) {
        unset($items[$key]);
    }
}


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.