Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find duplicate object in array and mark these [Javascript lodash]

I have an array with objects:

var test = [
	{
  	type: "home",
    name: "My home",
    country: "DE",
    postalZone: "1234",
    cityName: "GermanCity"
  },
	{
  	type: "home",
    name: "Some one else home",
    country: "DE",
    postalZone: "1234",
    cityName: "GermanCity"
  },
	{
  	type: "home",
    name: "My home",
    country: "DE",
    postalZone: "1234",
    cityName: "GermanCity"
  },
	{
  	type: "home1",
    name: "My home",
    country: "DE",
    postalZone: "1234",
    cityName: "GermanCity"
  },
	{
  	type: "home",
    name: "My home",
    country: "DE",
    postalZone: "1234",
    cityName: "GermanCity"
  }
];

I would like to mark the objects that they are duplicates, like this (notice the extra property, isDuplicate):

var test = [
	{
  	type: "home",
    name: "My home",
    country: "DE",
    postalZone: "1234",
    cityName: "GermanCity"
  },
	{
  	type: "home",
    name: "Some one else home",
    country: "DE",
    postalZone: "1234",
    cityName: "GermanCity"
  },
	{
  	type: "home",
    name: "My home",
    country: "DE",
    postalZone: "1234",
    cityName: "GermanCity",
    isDuplicate: true
  },
	{
  	type: "home1",
    name: "My home",
    country: "DE",
    postalZone: "1234",
    cityName: "GermanCity"
  },
	{
  	type: "home",
    name: "My home",
    country: "DE",
    postalZone: "1234",
    cityName: "GermanCity",
    isDuplicate: true
  }
];

If one of the above values change (type, name, country, postalZone or cityName), the object is unique.

I have tried the following for testing purpose. Getting only the unique objects for "type", does not work for me e.g.

_.uniq(test, "type");

Still getting all the array objects. Ofcourse I want to check on more object keys, not only on type, but on all object keys (type, name, country, postalZone or cityName).

The native array function "some", stops if it finds the first duplicate, for me it should not stop...

How can I achieve this?

I have Lodash v4.13.1.

like image 423
Anna Smother Avatar asked Sep 16 '16 11:09

Anna Smother


People also ask

How do I find duplicate values in an array Lodash?

To filter duplicates from an array, use Lodash's uniq() functio. This function will remove any duplicate values from the provided array.

How do I compare two arrays of objects in Lodash?

How do you compare objects in Lodash? In Lodash, we can deeply compare two objects using the _. isEqual() method. This method will compare both values to determine if they are equivalent.

How do you find duplicates in arrays?

The standard way to find duplicate elements from an array is by using the HashSet data structure. If you remember, Set abstract data type doesn't allow duplicates. You can take advantage of this property to filter duplicate elements.


2 Answers

Here is one solution with map() to change object if its found as duplicate and for finding duplicates i used find() and isEqual(). So if duplicate is found it will add property if not it will just return object.

var test = [{
  type: "home",
  name: "My home",
  country: "DE",
  postalZone: "1234",
  cityName: "GermanCity"
}, {
  type: "home",
  name: "Some one else home",
  country: "DE",
  postalZone: "1234",
  cityName: "GermanCity"
}, {
  type: "home",
  name: "My home",
  country: "DE",
  postalZone: "1234",
  cityName: "GermanCity"
}, {
  type: "home1",
  name: "My home",
  country: "DE",
  postalZone: "1234",
  cityName: "GermanCity"
}, {
  type: "home",
  name: "My home",
  country: "DE",
  postalZone: "1234",
  cityName: "GermanCity"
}];


var result = _.map(test, function(o, i) {
  var eq = _.find(test, function(e, ind) {
    if (i > ind) {
      return _.isEqual(e, o);
    }
  })
  if (eq) {
    o.isDuplicate = true;
    return o;
  } else {
    return o;
  }
})

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
like image 192
Nenad Vracar Avatar answered Sep 21 '22 13:09

Nenad Vracar


No need for lodash actually. By an invention of Object.prototype.compare() and with pure JS you might do this as follows;

Object.prototype.compare = function(o){
  var ok = Object.keys(this);
  return typeof o === "object" && ok.length === Object.keys(o).length ? ok.every(k => this[k] === o[k]) : false;
};

var myList = [
	{
  	type: "home",
    name: "My home",
    country: "DE",
    postalZone: "1234",
    cityName: "GermanCity"
  },
	{
  	type: "home",
    name: "Some one else home",
    country: "DE",
    postalZone: "1234",
    cityName: "GermanCity"
  },
	{
  	type: "home",
    name: "My home",
    country: "DE",
    postalZone: "1234",
    cityName: "GermanCity"
  },
	{
  	type: "home1",
    name: "My home",
    country: "DE",
    postalZone: "1234",
    cityName: "GermanCity"
  },
	{
  	type: "home",
    name: "My home",
    country: "DE",
    postalZone: "1234",
    cityName: "GermanCity"
  }
],
markedList = myList.reduce((p,c) => p.some(o => o.compare(c)) ? (c.isDuplicate = true, p.concat(c))
                                                              : p.concat(c),[]);
console.log(JSON.stringify(markedList,null,4));

You might of course prefer to convert Object.prototype.compare() to a proper function and adapt the code accordingly.

like image 42
Redu Avatar answered Sep 19 '22 13:09

Redu