2012-11-06 143 views
1

可能重复:
jquery remove duplicate li添加过滤器列出

我有一个列表,它看起来像下面的:http://jsfiddle.net/UwPTF/

<ul class="uol"> 
     <li>beta</li> 
     <li>gamma</li> 
     <li>alpha</li> 
    <li>beta</li> 
    <li>zeta</li> 
    <li>BETA</li>    
</ul> 

我有2个按钮,一个突出显示重复项目和其他项目以删除重复项目。

我正在尝试使用过滤功能。如果你能解释你的代码,非常感谢。

+0

在这情况下的数据从何而来,它是从数据库或你有机会获得一个脚本? – zz1433

+0

这是一个静态列表,如上例所示 –

+0

pmandell,不完全重复,因为我也在寻找突出重复项目的代码+一些解释来帮助我理解,而不是仅仅复制/粘贴和完成任务 –

回答

1

HTML

<ul id="list" class="uol"> 
    <li>beta</li> 
    <li>gamma</li> 
    <li>alpha</li> 
    <li>beta</li> 
    <li>zeta</li> 
    <li>BETA</li>    
</ul> 

<input id="find" type="button" value="Find" /> 
<input id="remove" type="button" value="Remove" />​ 

的JavaScript

$('#find').click(function(){ 
    $('#list li').filter(function(){ 
    return $(this).siblings().text().toUpperCase().indexOf($(this).text().toUpperCase()) != -1; 
    }).addClass('selecteditems'); 
}); 

$('#remove').click(function(){ 
    var removed = []; 
    $('.selecteditems').each(function(i, item){ 
    if($.inArray($(item).text().toUpperCase(), removed) != -1){ 
     $(item).remove(); 
    } 
    else{ 
     removed.push($(item).text().toUpperCase()); 
     $(item).removeClass('selecteditems'); 
    } 
    }); 
});​ 

当你点击查找按钮,过滤器被应用到每一个<li>项目在你的无序列表id为list。然后获取所有其他<li>项目,将它们的文本一起添加到一个字符串中并将其大写。然后它会检查当前的<li>项目是否包含在该字符串中。如果它在那里,它会返回true,所以它会将类selecteditems添加到它。

当您单击删除按钮时,它会删除除selecteditems类别的第一个<li>项目以外的所有项目,并从第一个<li>项目中删除该类别。

Check it out here.


如果你想绝对确保你检查,对个别项目,而不是检查,对所有项目的字符串,你可以改变你的代码,寻找到这一点:

$('#find').click(function(){ 
    $('#list li').filter(function(){ 
    var sibs = []; 
    $.map($(this).siblings(), function(sibling){ 
     sibs.push($(sibling).text().toUpperCase()); 
    }); 
    return $.inArray($(this).text().toUpperCase(), sibs) != -1; 
    }).addClass('selecteditems'); 
}); 
+0

非常感谢解释。你的例子工作完美 –

+0

这个删除部分将只适用于一个重复的单词,[在这里检查](http://jsfiddle.net/UwPTF/6/)(通知zeta被删除) – billyonecan

+0

@billyonecan - 现在更新了答案它没有。感谢您指出了这一点。 – Aust

0

那么,你必须比较每个项目与所有其他项目。为了有效地完成它,我会在所有列表项目中使用两个普通循环:在第一个循环中,根据每个项目的文本显示多少次,然后在第二个循环中只筛选计数大于1的项目。

代码应该是这样的:

function GetDupeItems() { 
    var oList = $(".uol"); 
    var allItems = oList.find("li"); 
    var mapping = {}; 
    allItems.each(function(index) { 
     var text = $(this).text().toLowerCase(); 
     if (!mapping[text]) 
      mapping[text] = 0; 
     mapping[text]++; 
    }); 

    return allItems.filter(function() { 
     return (mapping[$(this).text().toLowerCase()] > 1); 
    }); 
} 

我们纪念副本有:

GetDupeItems().addClass('duplicate'); 

它将添加一个类(如红色)和隐藏:(基本上从显示屏中删除)

GetDupeItems().hide(); 

Live test case

+0

您的示例还删除了原始项目..例如:Beta有2个重复项,但是当我在您的示例上单击Remove时,原始列表项也被删除 –

0

使用filter函数可以起到以下作用。

$('#find, #remove').click(function(e) { 
    $('.uol > li').each(function() { 
    var $this = $(this); 
    var thisText = $this.html().toUpperCase(); 

    var count = $('.uol > li').filter(function() { 
     return $(this).html().toUpperCase() == thisText; 
    }).length; 

    if (count > 1) { 
     if (e.target == $('#find')[0]) { 
     $this.addClass('duplicate'); 
     } else { 
     $('.uol > li').removeClass('duplicate'); 
     $this.remove(); 
     }  
    } 

    }); 
}); 

所以基本上,循环每个列表元素,然后用filter函数来检索列表中的很多元素是如何具有相同的文字作为当前,如果计数大于1的数,给元素类duplicate(注意:这不是最优化的)。

Here's a fiddle

+0

您的示例也删除了原始项目。例如:Beta有2个重复项,但是当我在您的示例上单击删除时,原始列表项也会被删除 –

+0

@TomHodder我已经编辑了我的答案以响应您的评论,应该能够正常工作现在好了。 – billyonecan