【问题标题】:Fastest way of deleting a value in a comma separated list删除逗号分隔列表中的值的最快方法
【发布时间】:2010-08-02 11:54:12
【问题描述】:

我有一个用逗号分隔的名称列表(它们可能包含其他字符),或者为空,但通常看起来像这样:

NameA,NameB,NameC

我需要创建一个函数来删除列表中存在的名称并恢复逗号分隔的结构。

例如:如果要删除 NameA,我应该以:

NameB,NameC

不是

,NameB,NameC

其余部分也是如此。

这是我想出来的,有没有更好的解决方案?

        $pieces = explode(",", $list);

        $key=array_search($deleteuser, $pieces);
        if(FALSE !== $key)
        {
            unset($pieces[$key]);
        }

        $list = implode(",", $pieces);

【问题讨论】:

  • 为什么需要“最快”的方式?有什么特别的原因吗?
  • 不,没什么特别的,但是explode/array_search/implode方法似乎很慢...
  • 这些方法很慢,因为它们是数组操作。字符串操作似乎更快。有关不使用数组操作的方法,请参阅下面的答案。

标签: php arrays string


【解决方案1】:

这应该很好用。您可能还对 PHP 的 fgetcsv 函数感兴趣。
文档:http://php.net/manual/en/function.fgetcsv.php

【讨论】:

    【解决方案2】:

    您可以使用array_splice 函数从数组中删除。偏移量 = array_search($deleteuser, $pieces) 和长度 = 1。

    【讨论】:

    • 为什么array_splice() 比使用unset() 更快?看起来你也没有照顾 false0 “gotcha”。
    【解决方案3】:

    如果您的应用程序数据如此之大,以至于您遇到了严重的延迟,那么您可能会遇到比这个 sn-p 代码更大的问题。也许是时候从头开始重新考虑您的数据存储和处理了。

    同时,这里有一些使用逗号分解 5001 元素数组,然后使用不同的技术删除值 4999 时的基准测试。 (速度实际上包括逗号分隔字符串的生成,但所有基准在这方面都是相同的)

    • explode() + array_search() + unset() + implode() (demo)
      系统时间:~.009 - .011s

      $pieces = explode(",", $list);
      if (($key = array_search($deleteuser, $pieces)) !== false) {
          unset($pieces[$key]);
      }
      echo implode(",", $pieces);
      

    • explode() + array_search() + array_splice() + implode() (demo)
      系统时间:~.010 - .012s

      $pieces = explode(",", $list);
      if (($key = array_search($deleteuser, $pieces)) !== false) {
          array_splice($pieces, $key, 1);
      }
      echo implode(",", $pieces);
      

    • explode() + foreach() + if() + unset() + break + implode() (demo)
      系统时间:~.011 - .012s

      $pieces = explode(",", $list);
      foreach ($pieces as $key => $value) {
          if ($value == $deleteuser) {
              unset($pieces[$key]);
              break;
          }
      }
      echo implode(",", $pieces);
      

      (注意:如果去掉break,循环可以去掉多次出现的针)


    • explode() + array_diff() + implode() (demo)
      系统时间:~.010 - .011s

      $pieces = explode(",", $list);
      $pieces = array_diff($pieces, [$deleteuser]);
      echo implode(",", $pieces);
      // or just: echo implode(',', array_diff(explode(",", $list), [$deleteuser]);
      

    • explode() + array_filter() + implode() (demo)
      系统时间:~.010 - .013s

      $pieces = explode(",", $list);
      $pieces = array_filter($pieces, function($v) use ($deleteuser) {
          return $v != $deleteuser;
      });
      echo implode(",", $pieces);
      

    • preg_quote() + preg_replace() (demo) (regex demo)
      系统时间:~.007 - .010s

      $needle = preg_quote($deleteuser, '/');
      echo preg_replace('/,' . $needle . '(?=,|$)|^' . $needle . ',/', '', $list);
      // if replacing only one value, declare preg_replace's 4th parameter as 1
      

    因此,虽然事实证明基于正则表达式的 sn-p 对于我任意变出的字符串长度来说稍微(不明显)更快,但您需要制定自己的基准来确定哪个是您的应用程序的最佳性能。

    也就是说,不要误会我的意思,我喜欢正则表达式,但是当需要修改模式时,正则表达式将是开发人员最容易“出错”的地方,而且我相信大多数开发人员会同意它的整体可理解性最差。

    【讨论】:

      【解决方案4】:

      你也可以试试这样的正则表达式(也许可以优化一下):

      $search = 'NameB';
      $list = 'NameA,NameB,NameC';
      $list = preg_match('/(^' . $search . ',)|(,' . $search. ')/', '', $list);
      

      【讨论】:

        猜你喜欢
        • 2017-09-13
        • 1970-01-01
        • 2012-05-22
        • 2010-10-14
        • 1970-01-01
        • 1970-01-01
        • 2010-10-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多