1

Possible Duplicate:
Remove duplicates from an array of objects in javascript

var arr = [{empID:100,empName:greg},{empID:101,empName:Math},{empID:100,empName:greg}];
var sorted_arr = arr.sort(); // You can define the comparing function here. 
                             // JS by default uses a crappy string compare.
var results = [];
for (var i = 0; i < arr.length - 1; i++) {
    if (sorted_arr[i + 1].empID != sorted_arr[i].empID) {
        results.push(sorted_arr[i]);
    }
}

alert(results);

I have an array of objects, but when i try to remove the duplicate object which matches the ID, it does not get removed. What's the issue with the code.

Community
  • 1
  • 1
theJava
  • 14,620
  • 45
  • 131
  • 172
  • Actually, this should be correct, this is what chrome returns me: `[{"empID":100,"empName":"greg"},{"empID":101,"empName":"Math"}]` If you're talking about the Elements in the results array http://jsbin.com/uwulun/1/edit – Moritz Roessler Dec 06 '12 at 12:45
  • Your array probably isn't sorted by `empID`, but by object hash. – Aesthete Dec 06 '12 at 12:45

3 Answers3

13

Your code has two problems:

  1. the sorting does not really work
  2. you forget to add the last element to the result

I would suggest the following alternative:

var arr = ...;
arr.sort( function( a, b){ return a.empID - b.empID; } );

// delete all duplicates from the array
for( var i=0; i<arr.length-1; i++ ) {
  if ( arr[i].empID == arr[i+1].empID ) {
    delete arr[i];
  }
}

// remove the "undefined entries"
arr = arr.filter( function( el ){ return (typeof el !== "undefined"); } );
Sirko
  • 72,589
  • 19
  • 149
  • 183
  • 4
    Instead of `delete arr[i]` use `arr.splice(i, 1)`. Delete just replaces that item with "undefined" but doesn't removeit from the array. – Adam Grant Jul 16 '13 at 17:29
  • @ajkochanowicz Though I do not have any evidence, I think the above code is better as it only creates a new array once, whereas using `splice()` would create a new array every time a duplicate is found. (and thus trigger unnecessary GC runs). – Sirko Jul 16 '13 at 18:53
  • Actually, it is nice that the indexes of each array item don't change--which can be dangerous in the middle of a loop. – Adam Grant Jul 16 '13 at 19:15
  • You can also check for arr[i+1] inside the loop to not be undefined like this: if ( arr[i+1] && arr[i].empID === arr[i+1].empID ). This is inportant when the loop goes to the last item. – Yura Loginov Nov 11 '13 at 11:49
6

Provided that empID is guaranteed to be a string or number, I would skip the sorting step and use an object as a hash of IDs that have already been seen:

var arr = [
    {empID:100,empName:"greg"},
    {empID:101,empName:Math},
    {empID:100,empName:"greg"}
];

var results = [];
var idsSeen = {}, idSeenValue = {};
for (var i = 0, len = arr.length, id; i < len; ++i) {
    id = arr[i].empID;
    if (idsSeen[id] !== idSeenValue) {
        results.push(arr[i]);
        idsSeen[id] = idSeenValue;
    }
}
Tim Down
  • 318,141
  • 75
  • 454
  • 536
1

Your sort function should really use a comparator, if you're going to be comparing items n and n+1

var sorted_arr = arr.sort(function(a,b) { return a.empID - b.empID; } );

This way you can be assured that sequential items in the list can possibly have duplicate empID properties.

Aesthete
  • 18,622
  • 6
  • 36
  • 45