46

Say I have a list of links with duplicate values as below:

<a href="#">Book</a>
<a href="#">Magazine</a>
<a href="#">Book</a>
<a href="#">Book</a>
<a href="#">DVD</a>
<a href="#">DVD</a>
<a href="#">DVD</a>
<a href="#">Book</a>

How would I, using JQuery, remove the dups and be left with the following for example:

<a href="#">Book</a>
<a href="#">Magazine</a>
<a href="#">DVD</a>

Basically I am looking for a way to remove any duplicate values found and show 1 of each link.

Georg Fritzsche
  • 97,545
  • 26
  • 194
  • 236
Keith Donegan
  • 26,213
  • 34
  • 94
  • 129

8 Answers8

134
var seen = {};
$('a').each(function() {
    var txt = $(this).text();
    if (seen[txt])
        $(this).remove();
    else
        seen[txt] = true;
});

Explanation:

seen is an object which maps any previously seen text to true. It functions as a set containing all previously seen texts. The line if (seen[txt]) checks to see if the text is in the set. If so, we've seen this text before, so we remove the link. Otherwise, this is a link text we see for the first time. We add it to the set so that any further links with the same text will be removed.

An alternative way to represent a set is to use an array containing all values. However, this would make it much slower since to see if a value is in the array we'd need to scan the entire array each time. Looking up a key in an object using seen[txt] is very fast in comparison.

interjay
  • 107,303
  • 21
  • 270
  • 254
11

Use jQuery method $.unique()

Detail see on http://api.jquery.com/jQuery.unique/

Vladimir
  • 183
  • 1
  • 2
  • 8
    Why. Why does *the included jQuery method* have 4 upvotes while an 8-line pile of side-effects is sitting at 29 and accepted? – Inaimathi Oct 14 '12 at 15:32
  • 23
    @Inaimathi: Maybe because this answer is incorrect. If two elements have the same text, `$.unique` will leave them both, so this doesn't do what the question asks. `$.unique` is only useful if you have two references to the same exact DOM element in an array, which isn't the case here. – interjay Nov 13 '12 at 17:38
  • 7
    Additionally, `$.unique` will only remove entries from an array, it won't remove them from the DOM. – interjay Nov 13 '12 at 17:51
  • There is a way to use $.uniqueSort() to perform this task. For an example, see [link](https://jsfiddle.net/s7154r23/). – Prince Deekay Nov 04 '16 at 21:16
  • As of jQuery 3.0, this method is deprecated and just an alias of jQuery.uniqueSort(). Please use that method instead. – yogihosting Jan 29 '17 at 12:51
6
// use an object as map
var map = {};
$("a").each(function(){
    var value = $(this).text();
    if (map[value] == null){
        map[value] = true;
    } else {
        $(this).remove();
    }
});
coolnalu
  • 375
  • 1
  • 7
1

@interjay @Georg Fritzsche

Your fix didn't work in my case so I build a different version:

var seen='';
   $('a').each(function(){
        var see=$(this).text();
        if(seen.match(see)){
            $(this).remove();}
        else{
            seen=seen+$(this).text();
        }
    });

Hopes this provides someone else with a valid alternative short fix just in case.

Idrees Khan
  • 7,702
  • 18
  • 63
  • 111
Ben Muircroft
  • 2,936
  • 8
  • 39
  • 66
  • 1
    I just stumbled on this... There is no reason why @interjay method is not working, plus, this has the potential to cause false positive... Try it if you have 3 links with those texts: "a","b" and "ab", the "ab" link will be removed... – Salketer Nov 06 '14 at 09:06
1
$(document).ready(function(){
   $("select").each(function () {
       var selectedItem = $(this).find('option').filter(':selected').text();
       var selectedItemValue = $(this).find('option').filter(':selected').val();
       $(this).children("option").each(function(x){
           if(this.text == selectedItem && $(this).val() != selectedItemValue) {
               $(this).remove();
            }
        });
    }); 
});
Saleh
  • 33
  • 7
  • am sry , i jst gave idea,,but above piece of code will retains the selected item & removes the duplicates of selected item. – Saleh Oct 09 '14 at 08:32
-1

Nice solution people. Here is mine

for (i = 0; i < $('li').length; i++) {
  text = $('li').get(i);
  for (j = i + 1; j < $('li').length; j++) {
    text_to_compare = $('li').get(j);
    if (text.innerHTML == text_to_compare.innerHTML) {
      $(text_to_compare).remove();
      j--;
      maxlength = $('li').length;
    }
  }
}

Greetings

-1

A quick and easy way would be

$("a").​​​​​​​​each(function(){
    if($(this).parent().length)
        $("a:contains('" + $(this).html() + "')").not(this).remove();
});​
-2
$('.photo').each(function (index) { 
    if (index > 0) { 
        $(this).remove(); 
    } 
});
Shaunak D
  • 20,588
  • 10
  • 46
  • 79