ove
ove

Reputation: 3202

Return object array matching duplicate property

What is the efficient way to return array with only duplicates?

array = [
{ name: 'name1', description:'desc1', place:'place1' },
{ name: 'name1', description:'desc1', place:'place2' },
{ name: 'name3', description:'desc3', place:'place3' },
{ name: 'name4', description:'desc4', place:'place4' },
{ name: 'name4', description:'desc4', place:'place4' },
{ name: 'name5', description:'desc5', place:'place5' }
]

In this case, we are only required to check the name and description properties for duplicates. Results should return:

duplicates = [
{ name: 'name1', description:'desc1', place:'place1' },
{ name: 'name4', description:'desc4', place:'place4' },
]

Any easy way of doing this?

Upvotes: 0

Views: 57

Answers (2)

Idan Beker
Idan Beker

Reputation: 363

This would would work for duplicates of 2.

let array = [
{ name: 'name1', description:'desc1', place:'place1' },
{ name: 'name1', description:'desc1', place:'place2' },
{ name: 'name3', description:'desc3', place:'place3' },
{ name: 'name4', description:'desc4', place:'place4' },
{ name: 'name4', description:'desc4', place:'place4' },
{ name: 'name5', description:'desc5', place:'place5' }
]

   
let duplicates = array.reverse()
            .filter((el,index)=> {
                let isDuplicate = index !== array.findIndex(({name,description})=> el.name === name && el.description === description);
               return isDuplicate});
              

              
console.log(duplicates)

Upvotes: 0

Ori Drori
Ori Drori

Reputation: 191946

Filter the array, and use a Set to check if the name and description already appeared, if so add to the output. If not add to Set:

const array = [{"name":"name1","description":"desc1","place":"place1"},{"name":"name1","description":"desc1","place":"place2"},{"name":"name3","description":"desc3","place":"place3"},{"name":"name4","description":"desc4","place":"place4"},{"name":"name4","description":"desc4","place":"place4"},{"name":"name5","description":"desc5","place":"place5"}]

const result = array.filter(function({ name, description }) {
  const key = `${name}-${description}`
  
  return this.has(key) || !this.add(key)
}, new Set())

console.log(result)

To show only one duplicate of each name and description group, use a Map instead, and count the number of appearances. Show only if the number is 2.

const array = [{"name":"name1","description":"desc1","place":"place1"},{"name":"name1","description":"desc1","place":"place2"},{"name":"name3","description":"desc3","place":"place3"},{"name":"name4","description":"desc4","place":"place4"},{"name":"name4","description":"desc4","place":"place4"},{"name":"name4","description":"desc4","place":"place4"},{"name":"name5","description":"desc5","place":"place5"}]

const result = array.filter(function({ name, description }) {
  const key = `${name}-${description}`
  const status = (this.get(key) || 0) + 1
  this.set(key, status)
  
  return status === 2
}, new Map())

console.log(result)

A solution for IE11 based on the Map solution:

const array = [{"name":"name1","description":"desc1","place":"place1"},{"name":"name1","description":"desc1","place":"place2"},{"name":"name3","description":"desc3","place":"place3"},{"name":"name4","description":"desc4","place":"place4"},{"name":"name4","description":"desc4","place":"place4"},{"name":"name4","description":"desc4","place":"place4"},{"name":"name5","description":"desc5","place":"place5"}]

const result = array.filter(function(o) {
  const key = o.name + '-' + o.description
  const status = (this.get(key) || 0) + 1
  this.set(key, status)
  
  return status === 2
}, new Map())

console.log(result)

Upvotes: 3

Related Questions