1

I am trying to use the reduce method on an array of objects, with each object being a person and flavors of ice cream they like. The goal is to reduce this array into a single object that contains the flavors as properties and the total number of times the flavor is listed as the values.

the data:

const data = [
     { name: 'Tyler', favoriteIceCreams: ['Strawberry', 'Vanilla', 'Chocolate', 'Cookies & Cream'] },
     { name: 'Richard', favoriteIceCreams: ['Cookies & Cream', 'Mint Chocolate Chip', 'Chocolate', 'Vanilla'] },
     { name: 'Amanda', favoriteIceCreams: ['Chocolate', 'Rocky Road', 'Pistachio', 'Banana'] },
     { name: 'Andrew', favoriteIceCreams: ['Vanilla', 'Chocolate', 'Mint Chocolate Chip'] },
     { name: 'David', favoriteIceCreams: ['Vanilla', 'French Vanilla', 'Vanilla Bean', 'Strawberry'] },
     { name: 'Karl', favoriteIceCreams: ['Strawberry', 'Chocolate', 'Mint Chocolate Chip'] }
 ];

This is what I have so far, but I am honestly not sure on how to do it.

let iceCreamTotals = {
         Strawberry: 0,
         Vanilla: 0,
         Chocolate: 0,
         CookiesCream: 0,
         MintChocolateChip: 0,
         RockyRoad: 0,
         Pistachio: 0,
         Banana: 0,
         FrenchVanilla: 0,
         VanillaBean: 0
     }

     data.reduce((total, current) => {

         return iceCreamTotals
     }, 0)
Colin Sygiel
  • 917
  • 6
  • 18
  • 29

4 Answers4

3

reduce this array into a single object, so the accumulator (second argument to reduce, optional) should be an object. Then on each step count the according property up for each element in the array (c.favoriteIceCreams.forEach). The p[cream] = (p[cream] || 0) + 1; is just syntax sugar for "add one if it exists otherwise set to 0+1".

const data = [
     { name: 'Tyler', favoriteIceCreams: ['Strawberry', 'Vanilla', 'Chocolate', 'Cookies & Cream'] },
     { name: 'Richard', favoriteIceCreams: ['Cookies & Cream', 'Mint Chocolate Chip', 'Chocolate', 'Vanilla'] },
     { name: 'Amanda', favoriteIceCreams: ['Chocolate', 'Rocky Road', 'Pistachio', 'Banana'] },
     { name: 'Andrew', favoriteIceCreams: ['Vanilla', 'Chocolate', 'Mint Chocolate Chip'] },
     { name: 'David', favoriteIceCreams: ['Vanilla', 'French Vanilla', 'Vanilla Bean', 'Strawberry'] },
     { name: 'Karl', favoriteIceCreams: ['Strawberry', 'Chocolate', 'Mint Chocolate Chip'] }
 ];
 
 console.log(data.reduce((p, c) => {
  c.favoriteIceCreams.forEach(cream => {
    p[cream] = (p[cream] || 0) + 1;
  });
  return p;
 }, {}));
ASDFGerte
  • 4,695
  • 6
  • 16
  • 33
1

You can collect the flavour names and counts as you go. The following creates an object with properties that are the flavours in the data with a count of how many times they occur.

var data = [
     { name: 'Tyler', favoriteIceCreams: ['Strawberry', 'Vanilla', 'Chocolate', 'Cookies & Cream'] },
     { name: 'Richard', favoriteIceCreams: ['Cookies & Cream', 'Mint Chocolate Chip', 'Chocolate', 'Vanilla'] },
     { name: 'Amanda', favoriteIceCreams: ['Chocolate', 'Rocky Road', 'Pistachio', 'Banana'] },
     { name: 'Andrew', favoriteIceCreams: ['Vanilla', 'Chocolate', 'Mint Chocolate Chip'] },
     { name: 'David', favoriteIceCreams: ['Vanilla', 'French Vanilla', 'Vanilla Bean', 'Strawberry'] },
     { name: 'Karl', favoriteIceCreams: ['Strawberry', 'Chocolate', 'Mint Chocolate Chip'] }
 ];
 
 var flavours = data.reduce(function(acc, obj) {
  // for each flavour, add it to the accumulator if it's not already there
  // and increament its count
  obj.favoriteIceCreams.forEach(function(flavour) {
    if (!acc[flavour]) {
      acc[flavour] = 0;
    }
    ++acc[flavour];
  });
  return acc;
}, Object.create(null));
 
console.log(flavours);
RobG
  • 142,382
  • 31
  • 172
  • 209
0

You can use for..of loop, Object.hasOwnProperty() to check if property is set at object, if true increment value, else set value to 0

let res = {}
for (let {favoriteIceCreams} of data) 
  for (let iceCream of favoriteIceCreams) 
    res[iceCream] = res.hasOwnProperty(iceCream) ? ++res[iceCream] : 1;
guest271314
  • 1
  • 15
  • 104
  • 177
0

Your problem has two aspects. The first is gathering all the flavors from all the people. The second is counting the frequency of each flavor. Your code will be simpler, and easier to debug, and more readable, if you separate out these two aspects. Gathering all the flavors is just

const flavors = [].concat(...data.map(({favoriteIceCreams}) => favoriteIceCreams));

Or if you prefer:

const flavors = [];

for (const {favoriteIceCreams} of data) flavors.push(...favoriteIceCreams);

There are many solutions here on SO about counting the frequency of occurrences in an array. Consider this one.