Home > Mobile >  Find duplicates and update their values in JavaScript array
Find duplicates and update their values in JavaScript array

Time:08-27

I was originally iterating through my array to remove any duplicates and only to return the unique values. However, I was wondering if it was possible to identify the duplicates and update their label in the original array in order to keep some of the original data that they contain. As of now, I been removing duplicates by doing the following:

     const removeDuplicates = arrayCollection
        .filter((link, i) => i === arrayCollection.findIndex((l) => (
          l.collectionTitle === link.collectionTitle
        )));

What I would like to do is for the collection title to attach something like "Link (0), Link (1)" if they share the same title. Overall, I'm trying to find a way to not remove the duplicates after finding them but rather to append something to differentiate them in the original array collection.

a sample of arrayCollection:

[
  {id: '1', collectionTitle: '456'},
  {id: '2', collectionTitle: '123'},
  {id: '3', collectionTitle: '123'},
];

the desired output of updating duplicates:

[
  {id: '1', collectionTitle: '456'},
  {id: '2', collectionTitle: '123 (0)'},
  {id: '3', collectionTitle: '123 (1)'},
];

CodePudding user response:

First I group by the title so I can count how many of each. I use the famous array reduce method for that. Then use that grouped object to reconstruct the names.

var arrayCollection = [
  {id: 1, collectionTitle: "Hello"},
  {id: 2, collectionTitle: "Goodbye"},
  {id: 3, collectionTitle: "Hello"},
];

var obj = arrayCollection.reduce(function(agg, item) {
  agg[item.collectionTitle] = agg[item.collectionTitle] || []
  agg[item.collectionTitle].push(item)
  return agg;
}, {})

var result = [];
Object.values(obj).forEach(function(arr) {
  if (arr.length == 1) {
    result.push(arr[0])
  } else {
    for (var i = 0; i < arr.length; i  ) {
      arr[i].collectionTitle  = " ("   i   ")";
      result.push(arr[i])
    }
  }
})
console.log(result)

CodePudding user response:

One of the fastest and most customizable ways to do this:

let result = [];
let dup = {}

for (let x = 0; x < arr.length; x  ){
  if (dup[arr[x]]) {
    result.push(‘whatever u want’);
  } else {
    result.push(arr[x]);
    dup[arr[x]] = true;
  }
}

CodePudding user response:

If you don't mind that first duplicate is not labelled, this will work:

const input = [
    {id: '1', collectionTitle: '456'},
    {id: '2', collectionTitle: '123'},
    {id: '3', collectionTitle: '123'},
]

const result = input.map((current, i, array) => {
    // Number of duplicates so far
    const duplicatesCount = array
      .slice(0, i)
      .filter(el => el.collectionTitle.startsWith(current.collectionTitle))
      .length
      
    return {
        id: current.id,
        collectionTitle: duplicatesCount > 0
          ? `${current.collectionTitle} (${duplicatesCount})`
          : current.collectionTitle,
    }
})

console.log(result)

It is not a good solution performance-wise (nested .slice and .filter inside .map), but the code itself is relatively concise.

  • Related