'Get count of same values in array of object

Suppose I have an array of object:

const apple = [{"bookName" :'Harry Pottar',part:"1"},{"bookName" :'Harry Pottar',part:"2"},
               {"bookName": 'LOTR',part:"1"},{"bookName": 'LOTR',part:"2"},{"bookName": 'LOTR',part:"3"}]

I want to get count of all common values along with the value name as :

   Expected O/P : [{"Harry Pottar":2},{"LOTR":3"}]

For this I tried as:

const id = "Harry Pottar";
const count = array.reduce((acc, cur) => cur.bookName === id ? ++acc : acc, 0);

As this gives the count, by this I can get count for each bookName. But how can I achieve my expected O/P scenario.

If anyone needs any further information please do let me know.



Solution 1:[1]

Create a map from your data keyed by the book names, where the corresponding values are the objects you want in the output, with the count set to zero (you can use the computed property name syntax for the object's dynamic property). Then iterate the data again to increment the counters. Finally extract the values from the map into an array:

const apple = [{"bookName" :'Harry Pottar',part:"1"},{"bookName" :'Harry Pottar',part:"2"},
               {"bookName": 'LOTR',part:"1"},{"bookName": 'LOTR',part:"2"},{"bookName": 'LOTR',part:"3"}];

let map = new Map(apple.map(({bookName}) => [bookName, { [bookName]: 0 }]));
for (let {bookName} of apple) map.get(bookName)[bookName]++;
let result = Array.from(map.values());

console.log(result);

Solution 2:[2]

You were pretty close. You don't necessarily need to have those objects in an array though. Just have an object with the booknames as the property keys. It would make it easier to manage.

If you then want to create an array of objects from that data you can use map over the Object.entries of that object.

const apple = [{"bookName" :'Harry Pottar',part:"1"},{"bookName" :'Harry Pottar',part:"2"},{"bookName": 'LOTR',part:"1"},{"bookName": 'LOTR',part:"2"},{"bookName": 'LOTR',part:"3"}];

const out = apple.reduce((acc, { bookName }) => {
  
  // If the property doesn't exist, create it
  // and set it to zero, otherwise increment the value
  // of the existing property
  acc[bookName] = (acc[bookName] || 0) + 1;
  return acc;
}, {});

console.log(out);

const result = Object.entries(out).map(([ key, value ]) => {
  return { [key]: value };
});

console.log(result);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2