按值删除数组项

177

我需要移除给定值的数组项:

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

有没有更短(更高效)的方法可以实现这个?

10个回答

435

这可以用一个简单的一行代码实现。

有这个数组:

$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函数是非破坏性的,它返回一个新的数组。 - Alejandro García Iglesias
2
@srcspider 为什么不呢?$referenced = array_diff($referenced, $items_to_remove); - Alejandro García Iglesias
1
$referenced 现在指向一个新的数组,你想要改变的那个数组仍然具有旧的值。 - srcspider
2
@srcspider,那么你告诉我这里发生了什么事情... http://codepad.org/11ZhiFP0 - Alejandro García Iglesias
1
我的错;PHP的变量别名技巧总是让我绊倒 >.> - srcspider
显示剩余2条评论

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方法更易读。点赞 - kendepelchin
@zombat 我想知道顺序是否与结果有关。可能洗牌将我们正在搜索的值放得更靠近前面或后面。除此之外... +1 - General Redneck

34

怎么样:

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

17

$arr中删除$rm_val

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
您的解决方案仅在数组中具有唯一值时有效。
请参见:
<?php
$trans = array("a" => 1, "b" => 1, "c" => 2);
$trans = array_flip($trans);
print_r($trans);
?>

更好的方法是使用array_search取消设置,必要时在循环中使用。

你是对的,但在这种特殊情况下,我相信数值是唯一的 :) - Marek

6

3
我刚刚阅读了这份文档,它推荐使用array_keys()函数来查找与某个值相关联的所有键。 - Savageman
@Savageman - 同意。我进行了快速基准测试,对于这个任务,array_keys()似乎比array_search()表现更好。 - zombat

5

无翻转:

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

5
function deleteValyeFromArray($array,$value)
{
   foreach($array as $key=>$val)
   {
      if($val == $value)
      {
         unset($array[$key]);
      }
   }
   return $array;
}

4
您可以使用array_splice函数进行此操作。参考:array_splice
array_splice($array, array_search(58, $array ), 1);

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