JavaScript+;用于检查表行冗余的jQuery函数
我使用js+jQuery编写了这个函数 下面是一个指向JSFIDLE的链接,它显示了我的问题:JavaScript+;用于检查表行冗余的jQuery函数,javascript,jquery,html-table,matching,redundancy,Javascript,Jquery,Html Table,Matching,Redundancy,我使用js+jQuery编写了这个函数 下面是一个指向JSFIDLE的链接,它显示了我的问题: 此函数的目标是扫描一个表并检查具有某些字段(td)值匹配的行。然后为行分配一个类,表示它们是否唯一,匹配行的数量将打印到每行的最终字段(td)中 它基本上使用这种结构的嵌套循环: 对于每一行。。。 扫描整个表以查找匹配项 我识别行的方法是将每行的字段(td)文本连接到每行的最终字段(td)上的rowid属性中 当前的函数工作正常,但对于大表~2000行,它的速度非常慢 必须有一种更有效、更优雅的方法来
此函数的目标是扫描一个表并检查具有某些字段(td)值匹配的行。然后为行分配一个类,表示它们是否唯一,匹配行的数量将打印到每行的最终字段(td)中
它基本上使用这种结构的嵌套循环:
对于每一行。。。
扫描整个表以查找匹配项
我识别行的方法是将每行的字段(td)文本连接到每行的最终字段(td)上的rowid属性中
当前的函数工作正常,但对于大表~2000行,它的速度非常慢
必须有一种更有效、更优雅的方法来实现这一点。任何帮助都将不胜感激 为每个表项创建哈希值,并在检查重复项之前使用哈希表或对其排序,因此您只需要比较相邻项。更优雅的方法是在构建此表之前在数据级别执行此操作 下面是一个使用关联数组存储结果,然后对其进行迭代的示例:
var rowIdCnt={};
函数unqOrMsgTest(){
//商店在这里计数
var rowIdCnt={};
//循环检查tds
$(“#binning tr td[col=check]”)。每个(函数(){
//抓取行标识符以对照其他行进行检查
var rowId=$(this.attr(“rowId”);
if(rowIdCnt中的rowId){
rowIdCnt[rowId]++;
}否则{
rowIdCnt[rowId]=1;
}
});
//现在迭代每个计数并适当更新表:
$.each(rowIdCnt,函数)(rowId,cnt){
//这种逻辑选择一个类来分配行
var resultClass=“notUnique”;
if(cnt<2){
resultClass=“唯一”;
}
//应用row类并将冗余号打印到td中
$('#binning tr td[rowid='+rowid+']').text(cnt.parent().addClass(resultClass);
});
}
这里有一种更好的预成型方法。我已删除了尽可能多的冗余DOM调用,并更正了无效属性(HTML标记只能支持某些属性..自定义属性需要以数据-
作为前缀)
以下是我推荐的解决方案:
函数unqOrMsgTest(){
变量行=$(“#binning tbody”).children('tr');
var totalRows=rows.length;
var idLookup={};
变量i、rowId、resultClass、checkColumn、rowCount、row;
//循环所有行,转换为jQuery对象并跟踪ID
对于(i=0;i
与上面建议使用关联数组(或哈希)存储id和计数的答案类似,我还删除了对list.each(function(){…})
的所有调用,并最小化了从dom元素到jQuery对象的转换次数
我之所以不使用each
,是因为每次迭代都会创建一个新的匿名函数,还调用了从this到$(this)的冗余转换,更不用说堆栈抖动了。只需说一个简单的for循环就足够了,而且速度更快
有关jQuery陷阱的更多信息,请查看
$(function(){//这只是为了启动函数
$(“#unqOrMsgTestFire”)。单击(unqOrMsgTest);
$(“#繁殖”)。单击(函数(){
var blueprint=$(“#binning tbody tr”).first();
对于(变量i=0;i<1000;i++)
blueprint.clone().appendTo(“#binning tbody”).find('td[rowid')).attr('rowid',Math.floor(Math.random()*500));
});
});
函数unqOrMsgTest(){
console.profile();
var-toCheck=$(“#binning>tbody>tr>td[col=check]”,
忽略={},
居里,
当前正在处理,
罗萨蒙特,
我
i=toCheck.length-1;
而(i>=0){
curId=toCheck.eq(i).attr(“rowid”);
如果(!(居里忽略)){
忽略[curId]=未定义;
currentlyProcessing=$(“#binning>tbody>tr>td[rowid=“+curId+”);
rowsAmount=currentlyProcessing.length;
当前处理
.text(rowsAmount)
.parent().attr('class',rowsAmount>1?“非唯一”:“唯一”);
}
我--;
}
console.profileEnd();
}
rowsAmount=currentlyProcessing.length;
当前处理
.text(rowsAmount)
.parent().attr('class',rowsAmount>1?“非唯一”:“唯一”);
toCheck=toCheck.not(当前处理);
}
}
$(“#binning tbody”)。儿童('tr')
-为什么不$(“#binning tbody>tr”)
?谢谢。它确实更干净,但没有明显的性能改进。谢谢,vucetica。桌子是动态的;它通过ajax调用反复追加。无法直接访问数据,因此它需要来自表@mightyuhu建议将数据提取到散列中,然后使用它
var rowIdCnt = {};
function unqOrMsgTest() {
// Store counts here
var rowIdCnt = {};
// loop through check tds
$("#binning tr td[col=check]").each(function() {
// grab row identifer to check against other rows
var rowId = $(this).attr("rowid");
if (rowId in rowIdCnt) {
rowIdCnt[rowId] ++;
} else {
rowIdCnt[rowId] = 1;
}
});
// Now iterate over each count and update the table appropriately:
$.each(rowIdCnt, function(rowId, cnt) {
//this bit of logic picks a class to assign rows
var resultClass = "notUnique";
if (cnt < 2) {
resultClass = "unique";
}
//apply the row class and print the redundancy number into td
$('#binning tr td[rowid='+rowId+']').text(cnt).parent().addClass(resultClass);
});
}
$(document).ready(function(){ //this is just to fire the function
$("#unqOrMsgTestFire").click(function(){
unqOrMsgTest();
});
});
function check_unique(row, collection) {
var unique = true, rowid = $(row).children('td[data-col=check]')[0].getAttribute('data-rowid');
collection.each(function() {
if( $(this).children('td[data-col=check]')[0].getAttribute('data-rowid') == rowid ) {
unique = false;
}
});
return unique;
}
function unqOrMsgTest() {
var collection = $("#binning tbody").children('tr');
collection.each(function(i, el){
el.className += check_unique( el, collection.not(el) ) ? ' unique' : 'notUnique';
});
}
function unqOrMsgTest() {
var rows = $("#binning tbody").children('tr');
var totalRows = rows.length;
var idLookup = {};
var i, rowId, resultClass, checkColumn, rowCount, row;
// loops through all rows, convert to jQuery objects and track the IDs
for (i = 0; i < totalRows; i++)
{
row = $(rows[i]);
rowId = row.children('td[col="check"]').attr("rowid");
rows[i] = row;
idLookup[rowId] = (rowId in idLookup) ? idLookup[rowId] + 1 : 1;
}
// loop through each row and check them for redundancy
for (var i = 0; i < totalRows; i++ )
{
// grab row identifer to check against the id lookup
row = rows[i];
checkColumn = row.children('td[col="check"]');
rowId = checkColumn.attr("rowid");
//this bit of logic picks a class to assign rows
rowCount = idLookup[rowId];
resultClass = rowCount < 2 ? "unique" : "notUnique";
//apply the row class and print the redundancy number into td
checkColumn.text(rowCount);
row.attr("class", resultClass);
};
}
$(function(){ //this is just to fire the function
$("#unqOrMsgTestFire").click(unqOrMsgTest);
$("#spawn").click(function(){
var blueprint = $("#binning tbody tr").first();
for(var i = 0; i < 1000; i++)
blueprint.clone().appendTo("#binning tbody").find('td[rowid]').attr('rowid', Math.floor(Math.random()*500));
});
});
function unqOrMsgTest() {
console.profile();
var toCheck = $("#binning > tbody > tr > td[col=check]"),
ignore = {},
curId,
currentlyProcessing,
rowsAmount,
i;
i = toCheck.length - 1;
while( i >= 0 ) {
curId = toCheck.eq(i).attr("rowid");
if( !(curId in ignore) ) {
ignore[curId] = undefined;
currentlyProcessing = $("#binning > tbody > tr > td[rowid=" + curId + "]");
rowsAmount = currentlyProcessing.length;
currentlyProcessing
.text( rowsAmount )
.parent().attr('class', rowsAmount > 1 ? "notUnique" : "unique");
}
i--;
}
console.profileEnd();
}
rowsAmount = currentlyProcessing.length;
currentlyProcessing
.text( rowsAmount )
.parent().attr('class', rowsAmount > 1 ? "notUnique" : "unique");
toCheck = toCheck.not( currentlyProcessing );
}
}