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.

2
  • 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 jsbin.com/uwulun/1/edit Commented Dec 6, 2012 at 12:45
  • Your array probably isn't sorted by empID, but by object hash. Commented Dec 6, 2012 at 12:45

3 Answers 3

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"); } );
Sign up to request clarification or add additional context in comments.

4 Comments

Instead of delete arr[i] use arr.splice(i, 1). Delete just replaces that item with "undefined" but doesn't removeit from the array.
@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).
Actually, it is nice that the indexes of each array item don't change--which can be dangerous in the middle of a loop.
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.
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;
    }
}

Comments

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.