【问题标题】:Fastest / most efficient way to compare two string arrays Javascript比较两个字符串数组Javascript的最快/最有效的方法
【发布时间】:2011-01-19 10:38:09
【问题描述】:

您好,我想知道是否有人可以就最快/最有效的方式在 javascript 中压缩两个字符串数组提供一些建议。

我正在开发一种基于用户输入的标签云类型的东西 - 输入的形式是书面文本,例如博客文章等。

因此,我有一个数组,我保留了不包含的单词 - is、a、the etc 等。

目前我正在做以下事情:

从输入字符串中删除所有标点符号,对其进行标记,将每个单词与排除数组进行比较,然后删除所有重复项。

比较是通过对输入文本中的每个单词的排除数组中的每个项目进行循环来执行的 - 这似乎是一种蛮力,并且会使 Internet Explorer 在超过几百个单词的数组上崩溃。

我还应该提到我的排除列表有大约 300 项。

任何帮助将不胜感激。

谢谢

【问题讨论】:

    标签: javascript arrays algorithm


    【解决方案1】:

    我不确定整个方法,但与其构建一个巨大的数组然后对其进行迭代,为什么不将“键”放入一个类似地图的对象中以便于比较?

    例如

    var excludes = {};//object
    //set keys into the "map"
    excludes['bad'] = true;
    excludes['words'] = true;
    excludes['exclude'] = true;
    excludes['all'] = true;
    excludes['these'] = true;
    

    那么当你想比较的时候……就去做

    var wordsToTest = ['these','are','all','my','words','to','check','for'];
    var checkWord;
    for(var i=0;i<wordsToTest.length;i++){
      checkWord = wordsToTest[i];
      if(excludes[checkword]){
        //bad word, ignore...
      } else {
        //good word... do something with it
      }
    }
    

    允许这些词通过['are','my','to','check','for']

    【讨论】:

    • 为了防止由于Object.prototype 的扩充而导致任何错误的可能性(例如,如果一个库已将each 方法添加到Object.prototype,“每个”将被视为错误示例代码中的单词),您可以使用 jshashtable (timdown.co.uk/jshashtable)。
    • 这是有道理的。我已经实现了它,并且 ti 在 Firefox 中工作得很好,但它仍然像以前一样崩溃。我想知道 ie 是否因此类问题而闻名,或者我的代码是否可以改进。
    • 编辑:我刚刚在 chrome、opera、firefox 和 safari 中测试了我的代码,它运行得非常快。在 ie 中它惨遭失败,我必须重新启动浏览器:(
    • @Tim Down:这是一个很好的理由,不要使用将默认命名空间混搭到无法识别的框架。
    • @David - 你有一个网址,我们可以看到整个事情吗?可能还有其他东西会导致 IE 崩溃。
    【解决方案2】:

    值得尝试将这些单词组合成一个正则表达式,然后与之进行比较。正则表达式引擎的优化可能允许搜索向前跳过搜索文本,这比您自己遍历单独的字符串更有效。

    【讨论】:

      【解决方案3】:

      您可以对字符串使用散列函数(我不知道 JS 是否有,但我相信 Google 叔叔可以提供帮助;])。然后,您将为排除列表中的所有单词计算哈希,并创建一个由这些哈希索引的布尔数组。然后只需遍历文本并根据该数组检查单词哈希。

      【讨论】:

      • 感谢您的回复,我一定会调查一下,但这能快多少,因为您实际上仍然在以相同的次数迭代相同数量的元素?
      • 不。您提出的算法具有 O(nmk) 复杂度,其中 n 是排除列表大小,m - 文本大小,k 是字符串比较中的平均操作数。提出的方法对于初始哈希具有 O(n) 复杂度,对于每次比较具有 O(m) 复杂度
      【解决方案4】:

      我已经采纳了斯昆利夫的回答,并修改如下:

      var excludes = ['bad','words','exclude','all','these']; //array
      

      现在让原型函数检查一个值是否在数组中:

      Array.prototype.hasValue= function(value) {
        for (var i=0; i<this.length; i++)
            if (this[i] === value) return true; 
        return false;
      }
      

      让我们测试一些单词:

      var wordsToTest = ['these','are','all','my','words','to','check','for'];
      var checkWord;
      for(var i=0; i< wordsToTest.length; i++){
        checkWord = wordsToTest[i];
        if( excludes.hasValue(checkWord) ){
          //is bad word
        } else {
          //is good word
          console.log( checkWord );
        }
      }
      

      输出:

      ['are','my','to','check','for']
      

      【讨论】:

        【解决方案5】:

        我会选择正则表达式版本

        text = 'This is a text that contains the words to delete. It has some <b>HTML</b> code in it, and punctuation!';
        deleteWords = ['is', 'a', 'that', 'the', 'to', 'this', 'it', 'in', 'and', 'has'];
        
        // clear punctuation and HTML code
        onlyWordsReg = /\<[^>]*\>|\W/g;
        onlyWordsText = text.replace(onlyWordsReg, ' ');
        
        reg = new RegExp('\\b' + deleteWords.join('\\b|\\b') + '\\b', 'ig');
        cleanText = onlyWordsText .replace(reg, '');
        
        // tokenize after this
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-11-12
          • 1970-01-01
          • 2012-03-15
          • 2015-07-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多