Roni Litman
Roni Litman

Reputation: 1001

remove duplicate objects from an array excluding specific keys in JavaScript

I have this array:

[{name: 'Brad', age: 30, isOlder: true, youngerBrother: 'Oleg'}, {name: 'Brad', age: 30, isOlder: false, youngerBrother: 'Michael'}]

I want to check if the items on the list are duplicated by specific keys.

for example - if name, age are the same on the list, the rows are duplicated, without paying attention to isOlder or youngerBrother.

I tried to use lodash _uniq but there is no option for excluding keys/paying attention to specific keys

Upvotes: 2

Views: 123

Answers (7)

Arnauld
Arnauld

Reputation: 6110

You can use .filter() and .some():

var list = [
  {name: 'Brad', age: 30, isOlder: true, youngerBrother: 'Oleg'},
  {name: 'Brad', age: 30, isOlder: false, youngerBrother: 'Michael'}
];

list = list.filter(function(outer, oPos) {
  return !list.some(function(inner, iPos) {
    return iPos > oPos && inner.name == outer.name && inner.age == outer.age;
  });
});

console.log(list);

However, it would be more efficient to start the inner loop at oPos + 1 directly:

var list = [
  {name: 'Brad', age: 30, isOlder: true, youngerBrother: 'Oleg'},
  {name: 'Brad', age: 30, isOlder: false, youngerBrother: 'Michael'}
];

list = list.filter(function(outer, oPos) {
  for(var iPos = oPos + 1; iPos < list.length; iPos++) {
    if(list[iPos].name == outer.name && list[iPos].age == outer.age) {
      return false;
    }
  }
  return true;
});

console.log(list);

Alternatively, we can build a list of the encountered composite keys as we are iterating in .filter(). Most browsers should implement if(keyList[key]) as a lookup in a hash table, making it quite fast.

var list = [
  {name: 'Brad', age: 30, isOlder: true, youngerBrother: 'Oleg'},
  {name: 'Brad', age: 30, isOlder: false, youngerBrother: 'Michael'}
];

var keyList = {};

list = list.filter(function(obj) {
  var key = obj.name + '|' + obj.age;
  
  if(keyList[key]) {
    return false;
  }
  keyList[key] = true;
  return true;
});

console.log(list);

Upvotes: 3

georg
georg

Reputation: 214949

Try uniqBy + a callback to extract a compound key from an array item:

uniqs = _.uniqBy(yourArray, x => x['name'] + x['age'])

In pure JS:

uniqBy = (xs, key) => {
    var keys = xs.map(key);
    return xs.filter((x, i) => keys.indexOf(key(x)) === i);
};

uniqs = uniqBy(yourArray, x => x['name'] + x['age'])

See https://stackoverflow.com/a/9229821/989121 for more details.

Upvotes: 2

Shintu Joseph
Shintu Joseph

Reputation: 962

You could use lodash _.uniqBy(arr,'key') it would suit you, as you are already using lodash

Upvotes: 3

Akash Bhandwalkar
Akash Bhandwalkar

Reputation: 901

Please try this

function isDuplicate(ArrayVar) {
    var tempObj = {};
    for (var key in ArrayVar) {
        if (object.hasProperty(ArrayVar[key].name)) {
            return true;
        }
        obj[ArrayVar[key].name] = true;
    }
    return false;
}

Upvotes: 2

Nenad Vracar
Nenad Vracar

Reputation: 122027

You could use Array#some and if name - age for any two or more objects are the same it will return true else false

var ar = [{name: 'Brad', age: 30, isOlder: true, youngerBrother: 'Oleg'}, {name: 'Brad', age: 30, isOlder: false, youngerBrother: 'Michael'}];

var result = ar.some(function(e) {
  if(!this[e.name + '|' + e.age]) {
    this[e.name + '|' + e.age] = true;
  } else {
    return true;
  }
}, {});

console.log(result)

Upvotes: 2

Robin Mackenzie
Robin Mackenzie

Reputation: 19319

Here's one option of doing this:

arr = [
    {name: 'Brad', age: 30, isOlder: true, youngerBrother: 'Oleg'}, 
    {name: 'Brad', age: 30, isOlder: false, youngerBrother: 'Michael'}
    ];

var result = checkDuplicateKeys(arr[0], arr[1], ['name', 'age']);
console.log(result);

function checkDuplicateKeys(obj1, obj2, keyList) {
    var propertyDuplicateCounter = 0;
    var result = false;

    for (var i=0; i<keyList.length; i++) {
        if (obj1.hasOwnProperty(keyList[i]) && obj2.hasOwnProperty(keyList[i])) {
            propertyDuplicateCounter += 1;
        }
    }

    if (propertyDuplicateCounter == keyList.length) {
        result = true;
    }

    return result;
}

Upvotes: 2

Morteza Tourani
Morteza Tourani

Reputation: 3536

You can use Array.prototype.filter

var data = [
  {name: 'Brad', age: 30, isOlder: true, youngerBrother: 'Oleg'}, 
 {name: 'Brad', age: 30, isOlder: false, youngerBrother: 'Michael'}
];

function distinctByField(arr, field) {
  var result = arr.filter(function(item) {
    var key = item[field];
    return this[key] ? false : (this[key] = true);
  }, Object.create(null));
  return result;
}

console.log(distinctByField(data, 'age'));

Upvotes: 1

Related Questions