anime
anime

Reputation: 165

Mark only second duplicated object in js array

I have a list of objects:

[{name: 'Elza'}, {name: 'Tom'}, {name: 'Elza'}]

I use the below methods to get duplicated objects(by name) and assign a prop isDuplicated:

const duplicatedNames = arrayOfObjects
  .map(e => e['name'])
  .map((e, i, final) => final.indexOf(e) !== i && i++)
  .filter(obj => arrayOfObjects[obj])
  .map(e => !arrayOfObjects[e]['name']);
const result = arrayOfObjects.filter((obj, i) => {
  return duplicatedNames.includes(obj.name) && Object.assign(obj, { isDuplicated: true });
});

I receive an array like:

[{name: 'Elza', isDuplicated: true}, {name: 'Tom'}, {name: 'Elza', isDuplicated: true}]

I would like to mark only the second occurrence of duplicate- so i would like the result to be:

[{name: 'Elza'}, {name: 'Tom'}, {name: 'Elza', isDuplicated: true}]

Can anyone know how to do it base on my code?

Upvotes: 0

Views: 103

Answers (5)

Ilijanovic
Ilijanovic

Reputation: 14914

Here is a function that checks if a name exist more then once.

let data = [{name:'Elza'}, {name:'Tom'}, {name:'Elza'}, {name: "Jerry"}, {name: "Jerry"}];

function checkDup(arr){
   let cache = [];
   return arr.map(({name}, index) => {
      if(!cache.find(el => el.name == name)){
         cache.push({name, index});
         return {name, index};
      }
      let { index: cacheIndex } = cache.find(el => el.name === name);
      return {name,index: cacheIndex , isDuplicated: true};
   })
}

console.log(checkDup(data));

Upvotes: 3

gazdagergo
gazdagergo

Reputation: 6691

You can use reduce with a helper object:

const collection = [{ name: 'Elza'}, { name: 'Tom'}, { name: 'Elza' }]

const helper = {}

const result = collection.reduce((acc, { name }) => {
  if (helper[name]) {
    return [...acc, { name, isDuplicate: true }]
  }
  helper[name] = 'x';
  return [...acc, { name }]
}, [])

console.log(result)

Upvotes: 0

Alessio Cantarella
Alessio Cantarella

Reputation: 5201

Given your original array A, you could create a temporary array B and, for each a element of A, check:

  • if B contains a.name, then set a.isDuplicated to true;
  • else, push a.name in B.

let A = [{name: 'Elza'}, {name: 'Tom'}, {name: 'Elza'}];
let B = [];
A.forEach(a => {
  if (B.includes(a.name)) {
    a.isDuplicated = true;
  } else {
    B.push(a.name);
  }
});
console.log(A);

Upvotes: 0

adiga
adiga

Reputation: 35222

You could create a Set of names. If the size of the set is same as after the name has been added, then it's duplicate record.

const input = [{name:'Elza'}, {name:'Tom'}, {name:'Elza'}],
      names = new Set;

for (const o of input)
  if (names.size === names.add(o.name).size)
    o.isDuplicate = true

console.log(input)

Upvotes: 3

thealpha93
thealpha93

Reputation: 778

You can try this:

let users = [{name:'Elza'}, {name:'Tom'}, {name:'Elza'}]

let flags = [], output = [];
users.forEach(user => {
  if (flags[user.name]) {
    output.forEach(item => {
      if (item.name === user.name) {
        item.isDuplicated = true
        output.push(user);
      }
    })
  } else {
    flags[user.name] = true;
    output.push(user);
  }
})

Upvotes: 0

Related Questions