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计数重复出现的主要内容,如果未能解决你的问题,请参考以下文章