JS计数重复出现

Posted

技术标签:

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

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

我有一张这样的桌子:

<table  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 次后触发 :) 【参考方案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 以及当文本包含对象属性标识符中不允许的字符时会发生什么? 嗯,属性总是可以使用[] 语法访问,所以使用任何字符串应该也可以。

以上是关于JS计数重复出现的主要内容,如果未能解决你的问题,请参考以下文章

2个小数位的JS计数器[重复]

求有序数组中不重复数字的出现次数

110,排序-计数排序

BigQuery拆分列并获取每个子字符串的计数[重复]

查找文件中出现的每个整数值的绝对计数

重复的累积计数