2

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

PinkeshGjr
  • 8,460
  • 5
  • 41
  • 56
Roni Litman
  • 923
  • 1
  • 8
  • 20
  • Please check : http://stackoverflow.com/questions/27854705/how-to-get-duplicates-in-a-javascript-array-using-underscore – Osman Corluk Jul 31 '16 at 13:45

7 Answers7

3

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

Shintu Joseph
  • 962
  • 7
  • 19
3

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);
Arnauld
  • 5,847
  • 2
  • 15
  • 32
2

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;
}
Morteza Tourani
  • 3,506
  • 5
  • 41
  • 48
2

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;
}
Robin Mackenzie
  • 18,801
  • 7
  • 38
  • 56
2

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)
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
2

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.

Community
  • 1
  • 1
georg
  • 211,518
  • 52
  • 313
  • 390
1

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'));
Morteza Tourani
  • 3,506
  • 5
  • 41
  • 48