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>