1

The following two lines appears in different locations of a page:

Line 1: <span class="specLink"><a title="Part A" href="/page1.aspx">Part A</a></span>
Line 2: <span class="specLink"><a title="Part A" href="/page1.aspx">Part A</a></span>

What I am doing currently is taking for each specLink class anchor and adding it to another DIV:

<div class="addSpecialties">
    //add those links in this DIV
</div>

So with the Javascript I have right now the out comes out line this:

<div class="addSpecialties">
    <a title="Part A" href="/page1.aspx">Part A</a>
    <a title="Part A" href="/page1.aspx">Part A</a>
</div>

However, What I would like to display is (just one of them because they are repetetive):

<div class="addSpecialties">
    <a title="Part A" href="/page1.aspx">Part A</a>
</div>

How can I modify my code so it only takes one occurrence of .specLink a.

Si8
  • 9,141
  • 22
  • 109
  • 221

5 Answers5

2

The question Remove Duplicates from JavaScript Array contains a full list of ways to remove the duplicates from an array. For example, an easy but naïve way is

function removeDuplicateElements(array) {
  return array.filter(function (item, index) {
    return array.indexOf(item) === index;
  });
}

However, it won't work for you. That function won't remove any of your elements.

That's because objects are compared by reference and, even if your elements look like the same, they are in fact different entities. So the code above won't detect any duplicate.

What you want is some kind of "loose" equality between objects. That is not simple in general.

But since you are only dealing with nodes, there is a perfect solution: isEqualNode

function removeDuplicateNodes(array) {
  return array.filter(function (item, index) {
    for(var i=0; i<index; ++i)
      if(item.isEqualNode(array[i]))
        return false;
    return true;
  });
}

See the difference:

var el1 = document.createElement('div'),
    el2 = el1.cloneNode(true);
removeDuplicateElements([el1, el2]); // [el1, el2], because el1 !== el2
removeDuplicateNodes([el1, el2]); // [el1], because el1.isEqualNode(el2)
Community
  • 1
  • 1
Oriol
  • 274,082
  • 63
  • 437
  • 513
1

If you are familiar with lodash, the uniq function sounds like what you are looking for.

_.uniq([2, 1, 2]);
// → [2, 1]

// isSorted = true
_.uniq([1, 1, 2], true);
// → [1, 2]

https://lodash.com/docs#uniq

errata
  • 23,596
  • 2
  • 22
  • 32
1

You must return 'true' to keep an element and 'false' to remove an element. Your 'removeDuplicateElements' function returns false, so as it executes, it deletes every element from the array. As @gnerkus suggested, modify your removeDuplicateElements() function to return the following:

return array.indexOf(item) === index;
Eric G.
  • 11
  • 2
1

Here is a function witch removes the duplicates a elements from your div

function removeDuplicateLinks() {
    var div                 = document.getElementsByClassName('addSpecialties')[0];
    var specialities        =  div.children;
    var uniqueSpecialities  = [];

    for (var i = 0; i < specialities.length; i++) {
        var elem = specialities[i];

        if (elem.nodeName === 'A') {
            var title = specialities[i].title;

            if (uniqueSpecialities.indexOf(title) === -1) {
                uniqueSpecialities.push(title);
            } else {
                div.removeChild(elem);
                i--;
            }
        }
    }
}

function removeDuplicateLinks() {
  var div = document.getElementsByClassName('addSpecialties')[0];
  var specialities = div.children;
  var uniqueSpecialities = [];

  for (var i = 0; i < specialities.length; i++) {
    var elem = specialities[i];

    if (elem.nodeName === 'A') {
      var title = specialities[i].title;

      if (uniqueSpecialities.indexOf(title) === -1) {
        uniqueSpecialities.push(title);
      } else {
        div.removeChild(elem);
        i--;
      }
    }
  }
}
.addSpecialties a { display: block; }
<button onclick="removeDuplicateLinks()">Remove duplicate links</button>

<div class="addSpecialties">
  <a title="Part A" href="#">Part A</a>
  <a title="Part A" href="#">Part A</a>
  <a title="Part A" href="#">Part A</a>
  <a title="Part A" href="#">Part A</a>
  <a title="Part B" href="#">Part B</a>
  <a title="Part A" href="#">Part A</a>
  <a title="Part B" href="#">Part B</a>
  <a title="Part A" href="#">Part A</a>
  <a title="Part B" href="#">Part B</a>
  <a title="Part A" href="#">Part A</a>
  <a title="Part C" href="#">Part C</a>
  <a title="Part C" href="#">Part C</a>
</div>
Ionut
  • 1,729
  • 4
  • 23
  • 50
0

You need to return the result of the filter:

function removeDuplicateElements(array) {
        return array.filter(function (item, index) {
            return array.indexOf(item) === index;
        });
    }
gnerkus
  • 11,357
  • 6
  • 47
  • 71