【问题标题】:Removing array item by value [duplicate]按值删除数组项[重复]
【发布时间】:2010-12-25 09:37:35
【问题描述】:

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

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

能否以更短(更高效)的方式完成?

【问题讨论】:

    标签: php arrays


    【解决方案1】:

    这可以用一个简单的单行来完成。

    拥有这个数组:

    $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')
    

    【讨论】:

    • 不,它确实适用于引用的数组,array_diff 函数是非破坏性的,它返回一个新数组。
    • @srcspider 为什么不呢? $referenced = array_diff($referenced, $items_to_remove);
    • $referenced 现在指向一个新数组,您要更改的数组仍然具有旧值。
    • @srcspider 好吧,那你告诉我这里发生了什么...codepad.org/11ZhiFP0
    • 我的错; php的变量别名噱头总是让我绊倒>.>
    【解决方案2】:

    您可以使用 array_splice 函数进行此操作参考:array_splice

    array_splice($array, array_search(58, $array ), 1);
    

    【讨论】:

      【解决方案3】:
      function deleteValyeFromArray($array,$value)
      {
         foreach($array as $key=>$val)
         {
            if($val == $value)
            {
               unset($array[$key]);
            }
         }
         return $array;
      }
      

      【讨论】:

        【解决方案4】:

        从$arr 中删除$rm_val

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

        【讨论】:

          【解决方案5】:

          怎么样:

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

          或多个值:

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

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

          【讨论】:

          • 如果 $id 是第一个数组元素则不起作用,最好这样: if ( ($key = array_search($id, $items)) !== false) unset($items[$键]);
          【解决方案6】:

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

          $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 方法更具可读性。点赞
          • @zombat 我想知道订单是否与结果有关。 shuffle 可能会将我们正在搜索的值放在更靠近前端或末尾的位置。除此之外……+1
          【解决方案7】:

          只有在数组中有唯一值时,您的解决方案才有效

          见:

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

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

          【讨论】:

          • 你是对的,但在这种特殊情况下,我很确定值是唯一的 :)
          【解决方案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;
              }
          }
          

          【讨论】:

            【解决方案9】:

            无翻转:

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

            【讨论】:

              【解决方案10】:

              【讨论】:

              • 我刚刚阅读了文档,它建议使用 array_keys() 来查找与某个值关联的所有键。
              • @Savageman - 同意。我运行了一个快速基准测试,array_keys() 似乎比array_search() 执行此任务更好。
              猜你喜欢
              • 2011-10-31
              • 2017-07-23
              • 1970-01-01
              • 2021-01-23
              • 2018-05-20
              相关资源
              最近更新 更多