urbz
urbz

Reputation: 2667

Remove objects in array with duplicate properties

Let's say I got an array like this:

var arr1 = [ 1, 1, 'a', 'a' ];

And I want to remove duplicates, this snippet is awesome:

var deduped = arr1.filter(function (el, i, arr) {
    return arr.indexOf(el) === i;
});

But I got this array, and I want to remove objects that has duplicate properties:

var obj1 = {
  name: "John",
  id: 1
};
var obj2 = {
  name: "Moe",
  id: 1
};
var obj3 = {
  name: "Jane",
  id: 2
};

var arr2 = [obj1, obj2, obj3];

How do I write a function to remove either one of (in this case) obj1 or obj2 since they have the same id?

I do not want to remove both!

JsFiddle

Reference for code snippet

Thanks in advance.

Upvotes: 5

Views: 2462

Answers (6)

SimPHP
SimPHP

Reputation: 65

Thanks https://stackoverflow.com/users/1746830/rayon, for https://stackoverflow.com/a/40784420/8462064

I have improved this for an instance where I have objects with different keys (some have id some have id2)

        var obj1 = {
          name: "John",
          id: 1
        };
        var obj2 = {
          name: "Moe",
          id: 1
        };
        var obj3 = {
          name: "Jane",
          id: 2
        };
        var obj4 = {
          name: "John",
          id2: 1
        };
        var obj5 = {
          name: "Moe",
          id2: 1
        };
        var obj6 = {
          name: "Jane",
          id2: 2
        };
        var arr2 = [obj1, obj2, obj3,obj4, obj5, obj6];
        
        let idArray = []
        let id2Array = []
        arr2 = arr2.filter(function ( el ) {
          if( typeof el["id"] != 'undefined' && !idArray[ el.id]  ){
            idArray[el.id] = true;
            return true;
          }
          else if(  typeof el["id2"] != 'undefined' && !id2Array[ el.id2 ]   ){
            id2Array[el.id2] = true;
            return true;
          }
          return false;
        }, Object.create(null));

Upvotes: 0

Hendrik Schmitz
Hendrik Schmitz

Reputation: 81

I just ran into the same problem and it turns out we can solve this problem using Array.prototype.findIndex()

const deduped = arr2.filter(function (el, i, arr) {
    return arr.findIndex(el2 => el2.id === el.id) === i;
});

Upvotes: 1

Umair
Umair

Reputation: 685

Consider that u have array with duplicate numbers

int a {1,2,3,4,5,5,6,4,7,1,2}

now pick the biggest integer from this array named as a. for example in this array it is 7 . Now create new array named as b with size the biggest number in array a.

int b[7]

now start traversing the array a. pick the number from each index for example at index 0 of array a it is 1 . now go to index 1 of array b and check if there it is written 0 write 1 there and if already 1 is written on that index then delete that number from array a. in this way you can delete all duplicates from array a.

Upvotes: 0

Rayon
Rayon

Reputation: 36609

Use Array#filter with thisArg

thisArg, Value to use as this when executing callback.

var obj1 = {
  name: "John",
  id: 1
};
var obj2 = {
  name: "Moe",
  id: 1
};
var obj3 = {
  name: "Jane",
  id: 'toString'
};

var arr2 = [obj1, obj2, obj3];
var filtered = arr2.filter(function(el) {
  if (!this[el.id]) {
    this[el.id] = true;
    return true;
  }
  return false;
}, Object.create(null));
console.log(filtered);

Upvotes: 8

Nina Scholz
Nina Scholz

Reputation: 386680

You could use a compact version of checking and assigning to a hash object.

var obj1 = { name: "John", id: 1 },
    obj2 = { name: "Moe", id: 1 },
    obj3 = { name: "Jane", id: 2 },
    arr2 = [obj1, obj2, obj3],
    filtered = arr2.filter(function(a) {
        return !this[a.id] && (this[a.id] = true);
    }, Object.create(null));

console.log(filtered);

Upvotes: 2

Bruno Bispo
Bruno Bispo

Reputation: 101

We can add a step to map all object IDs before

var arr2 = [obj1, obj2, obj3];

var ids = arr2.map(function(obj){
    return obj.id;
})

var deduped2 = arr2.filter(function (el, i, arr) {
    return ids.indexOf(el.id) === i;
});

Upvotes: 2

Related Questions