-1

Here is an example js array:

var arr = [
  {
    name: 'test1',
    price: 20,
    otherKey: 123,
    yetAnotherKey: 'val'
  },
  {
    name: 'test2',
    price: 10,
    otherKey: 11,
    yetAnotherKey: 'erewrwert'
  },
  {
    name: 'test1',
    price: 20,
    otherKey: 123,
    yetAnotherKey: 'val'
  }
]

Is there a way to find duplicate object (by all key/value pairs)? If so - how to do that? Thanks in advance.

hasan
  • 3,484
  • 1
  • 16
  • 23
stryker
  • 149
  • 1
  • 16

5 Answers5

3

There are many subjects on the matter, from deep mapping to external libraries (underscore is recommendable), but most often a JSON string is used. Not optimal, but easiest in use. Combined with an ES6 Set, the unique objects can be obtained with:

arr = [...new Set(arr.map(JSON.stringify))].map(JSON.parse);

var arr = [
  {
    name: 'test1',
    price: 20,
    otherKey: 123,
    yetAnotherKey: 'val'
  },
  {
    name: 'test2',
    price: 10,
    otherKey: 11,
    yetAnotherKey: 'erewrwert'
  },
  {
    name: 'test1',
    price: 20,
    otherKey: 123,
    yetAnotherKey: 'val'
  }
];

arr = [...new Set(arr.map(JSON.stringify))].map(JSON.parse);

console.log(arr);
Me.Name
  • 12,259
  • 3
  • 31
  • 48
1

Have you tried the Undescore JS library?

uniq_.uniq(array, [isSorted], [iteratee]) Alias: unique Produces a duplicate-free version of the array, using === to test object equality. In particular only the first occurence of each value is kept. If you know in advance that the array is sorted, passing true for isSorted will run a much faster algorithm. If you want to compute unique items based on a transformation, pass an iteratee function.

_.uniq([1, 2, 1, 4, 1, 3]);

=> [1, 2, 4, 3]

Since you want to implement for objects, here are plenty solutions using _.uniq() which you might want to have a look at - Removing duplicate objects with Underscore for Javascript

Yasser Shaikh
  • 46,934
  • 46
  • 204
  • 281
1

A naive approach: Note the inefficiency of using forEach. A force iteration over all the item even if a match was found.

var arr = [
      {
        name: 'test1',
        price: 20,
        otherKey: 123,
        yetAnotherKey: 'val'
      },
      {
        name: 'test2',
        price: 10,
        otherKey: 11,
        yetAnotherKey: 'erewrwert'
      },
      {
        name: 'test1',
        price: 20,
        otherKey: 123,
        yetAnotherKey: 'val'
      }
    ]

    function findFirstDuplicate(arr) {
      var retval = null
      arr.forEach(function(item) {
        arr.forEach(function(item2) {
            if(JSON.stringify(item) == JSON.stringify(item2)) {
            retval = item;
          }
        });
      });

      return retval;
    }

    console.log(findFirstDuplicate(arr));
Ryan
  • 14,392
  • 8
  • 62
  • 102
0

Assuming it’s enough to just decide whether an object o1 is a duplicate of o2 or not, you can try the following:

function isDuplicate(o1, o2) {
  return JSON.stringify(o1) == JSON.stringify(o2);
}
gsc
  • 1,559
  • 1
  • 13
  • 17
0

My solution using a map with the stringified element as the key

var arr = [
      {
        name: 'test1',
        price: 20,
        otherKey: 123,
        yetAnotherKey: 'val'
      },
      {
        name: 'test2',
        price: 10,
        otherKey: 11,
        yetAnotherKey: 'erewrwert'
      },
      {
        name: 'test1',
        price: 20,
        otherKey: 123,
        yetAnotherKey: 'val'
      }
    ]

function solution(arr) {
  let map = new Map();
  let res = [];
  arr.forEach(e => {
    let currKey = JSON.stringify(e);
    // if not seen by the map, put in the the map and push element to result array
    if (!map.get(currKey)) {
      map.set(currKey, true);
      res.push(e);
    } 
  });
  return res;
}

console.log(solution(arr))
Mμ.
  • 8,382
  • 3
  • 26
  • 36