Home > Blockchain >  Delete duplicates in an array but add a count property to see the number of duplicates
Delete duplicates in an array but add a count property to see the number of duplicates

Time:11-05

Basically if I had this array:

[{"id" = 1, "product" = "Book"}, {"id" = 1, "product" = "Book"}, {"id" = 1, "product" = "Book"}, {"id" = 2, "product" = "Chair"}]

It would turn into this array:

 [{"id" = 1, "product" = "Book", "count" = 3}, {"id" = 2, "product" = "Chair", "count" = 1}]

I am using react. Another option I have is to add the count property when making and adding to the array so that duplicates don't get added, but I am curious if there is a way to do it with an existing array.

Edit: If two products have the same id they are duplicates.

I have tried filtering the array by using the id, then getting the first object. I filtered the array again by id to get the length. Then I added a new property "count" to the first object which is the length of the filtered array, after that I added the first object to a new array. The problem with doing it this way is that I have to hard code this for every possible id even if it is not included in my array.

CodePudding user response:

Reduce the array to a Map (or even just a plain object) keyed by id (assuming that's all it takes to identify a duplicate).

The values of that map will be the array you're after.

const arr = [{"id":1,"product":"Book"},{"id":1,"product":"Book"},{"id":1,"product":"Book"},{"id":2,"product":"Chair"}]

const zipped = Array.from(arr.reduce((map, o) => {
  // check if id already registered
  if (map.has(o.id)) {
    // increment count
    map.get(o.id).count  
  } else {
    // otherwise, store the new object with count starting at 1
    map.set(o.id, { ...o, count: 1 })
  }
  return map
}, new Map()).values())

console.log(zipped)
.as-console-wrapper { max-height:100% !important; }
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

You could reduce the array into a new array with the count property added. The id property is assumed to be sufficient for considering uniqueness. If the element has already been seen then increment the count, otherwise append a new augmented element object.

const data = [{
  "id": 1,
  "product": "Book"
}, {
  "id": 1,
  "product": "Book"
}, {
  "id": 1,
  "product": "Book"
}, {
  "id": 2,
  "product": "Chair"
}];

const dedupedData = data.reduce((data, el) => {
  const index = data.findIndex(item => item.id === el.id);
  if (index !== -1) {
    data[index].count  ;
  } else {
    data.push({ ...el, count: 1 });
  }
  return data;
}, []);

console.log(dedupedData);
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related