【问题标题】:JS counting repeat occurrencesJS计数重复出现
【发布时间】:2013-04-04 23:14:18
【问题描述】:

我需要查找 td.aws 中的字符串是否出现超过 3 次,如果出现,则将该字符串放入新列表中。

我有一张这样的桌子:

<table width="100%" cellspacing="0" cellpadding="2" border="1" class="aws_data">
<tbody><tr bgcolor="#ECECEC"><th>URL (1,908)</th></tr>
<tr><td class="aws">/images/bullet3.png</td></tr>
<tr><td class="aws">/pdf-signing-tool/ErrorCode.properties</td></tr>
<tr><td class="aws">/pdf-signing-tool/Display.properties</td></tr>
<tr><td class="aws">/evcert.cfm</td></tr>
<tr><td class="aws">/evcert.cfm</td></tr>
<tr><td class="aws">/evcert.cfm</td></tr>
<tr><td class="aws">/evcert.cfm</td></tr>
<tr><td class="aws">/repository/03</td></tr>
<tr><td class="aws">/repository/0</td></tr>
etc

<div id="problems"></div>

到目前为止我有:

$('.aws').each(function(){
var temp = $(this).text();
var count = temp.match('/'+temp+'/g');  

if (count.length > 3)
{
    thisString = $(this).text();
    $('#problems').append(thisString)
}

});

谁能帮忙,目前我刚刚收到 JS 错误“count is null”

JS FIDDLE

【问题讨论】:

  • 正则表达式是/regex/mods 形式的文字,而不是字符串。要将字符串用作正则表达式,请通过new RegExp 运行它(但请注意,不需要斜杠,修饰符是第二个参数)。
  • 在您给出的示例中,为什么预期计数会超过 3?
  • 你能举一个更好的例子吗?如果您获取元素的整个文本,则文本只会在元素内部出现一次。您尝试的代码对我来说没有多大意义。您只是在测试字符串是否与自身匹配,应该始终如此,但结果将始终是长度为 1 的数组。
  • 对不起,这个例子很糟糕。我已经添加了一个现在出现了 3 次的内容。我试图基本上看看是否有重复。所以“evcert.cfm”现在出现了 3 次
  • @Barney 将其编辑为四次,因为代码仅在 发生 3 次后触发 :)

标签: javascript jquery logic


【解决方案1】:

Example

//store the counts for each "text" occurrence in a hash table
var countHash = {}; 

//iterate over your tds
$('.aws').each(function(){

    //pull of the text
    var temp = $(this).text();

    //has it already been added to the list? 
    //see: 'countHash[temp] = false;' below.
    if(countHash[temp] === false){return;}

    //increment the occurrence count
    //or set to 1 if this is the first occurrence.
    countHash[temp] = (countHash[temp] || 0) + 1; 

    //have more than three been found?
    if (countHash[temp] > 3)
    {
        //add to your list
        $('#problems').append(temp);

        //ignore future occurrences
        countHash[temp] = false; 
    }
});

【讨论】:

    【解决方案2】:

    应该使用new RegExp() 创建这样的正则表达式,如 cmets 中所述。除此之外,如果使用括号和问号之类的东西,使用每个表格单元格的内部文本可能会导致无效的正则表达式。所以在这种情况下,我建议不要这样做。

    您可以在遍历每个 td.aws 时像这样进行频率计数:

    var frequencies = {};
    
    $('td.aws').each(function() {
        var key = $(this).text(),
        freq = frequencies[key] || 0;
    
        // increase the frequency and check if it goes above 3
        if (++freq > 3) {
            $('#problems').append(key);
            freq = -Infinity;
        }
    
        frequencies[key] = freq;
    });
    

    Demo

    对象frequencies在其属性中保留了每个词的频率;一旦达到一定数量,它就会做你需要的任何事情。

    【讨论】:

      【解决方案3】:
      var count = {};
      $(".aws").each(function(i,v) {
          var temp = $(v).text();
          var current = count[temp];
          if (!current) {
              current = 0;
          }
          current++;
          count[temp] = current;
          if (current > 3) {
             $("#problems").append("<p>"+temp+"</p>");
          }
      }
      

      我不确定您是否要从旧列表中删除出现三次的项目,所以我没有添加它

      【讨论】:

      • 这将多次附加一个项目(每次其频率超过 3 一次)。
      【解决方案4】:

      您的问题在这里:'/'+temp+'/g' 您不能在正则表达式文字中使用变量。您必须将正则表达式构建为字符串:

      var tempRegex = new RegExp(temp, 'g');
      var count = temp.match(tempRegex);
      

      您的代码中似乎存在较大的逻辑问题。现在你正在构建一个正则表达式来查看文本是否匹配自身,这总是会的。我认为您正在尝试搜索所有 TD 以确定是否存在重复项。试试这种方法:

      var items = [];
      
      $('.aws').each(function(){
          var currentText = $(this).text();
          var duplicate = false;
      
          for (var i = 0; i < items.length; i++) {
              if (items[i].text === currentText) {
                  items[i].count++;
      
                  if (items[i].count > 2) {
                      console.log('found more than 2 of ' + currentText);
                      $('#problems').append(currentText)
                  }
      
                  duplicate = true;
                  break;
              }
          }
      
          if (!duplicate) {
              items.push({ text: currentText, count: 1});
          }
      });
      

      http://jsfiddle.net/qT6Nz/2/

      【讨论】:

      • 这将多次追加副本(每次超过 2 次时追加一次)。此外,最好使用对象的属性来实现频率计数。
      • @Jack 以及当文本包含对象属性标识符中不允许的字符时会发生什么?
      • 嗯,属性总是可以使用[] 语法访问,所以使用任何字符串应该也可以。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-24
      • 1970-01-01
      • 2012-06-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多