如何在对象数组上使用reduce方法创建一个具有每个值的总值的单个对象?

时间:2017-08-06 04:14:36

标签: javascript

我试图在一个对象数组上使用reduce方法,每个对象都是一个人,他们喜欢冰淇淋的味道。目标是将此数组减少为单个对象,该对象包含作为属性的flavor,以及将flavor列为值的总次数。

数据:

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'] }
 ];

这是我到目前为止所做的,但老实说我不确定如何做到这一点。

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)

4 个答案:

答案 0 :(得分:3)

reduce this array into a single object,所以累加器(reduce的第二个参数,可选)应该是一个对象。然后在每个步骤中计算数组中每个元素的相应属性(c.favoriteIceCreams.forEach)。 p[cream] = (p[cream] || 0) + 1;只是&#34的语法糖;如果存在则添加一个,否则设置为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;
 }, {}));




答案 1 :(得分:1)

您可以随时收集风味名称和计数。下面创建一个对象,其属性是数据中的风格,并计算它们出现的次数。

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);

答案 2 :(得分:0)

您可以使用for..of循环,Object.hasOwnProperty()来检查属性是否设置为对象,是否为真增量值,否则将值设置为0

let res = {}
for (let {favoriteIceCreams} of data) 
  for (let iceCream of favoriteIceCreams) 
    res[iceCream] = res.hasOwnProperty(iceCream) ? ++res[iceCream] : 1;

答案 3 :(得分:0)

你的问题有两个方面。第一个是收集所有人的所有口味。第二个是计算每种口味的频率。如果将这两个方面分开,您的代码将更简单,更容易调试,更易读。收集所有口味只是

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

或者如果您愿意:

const flavors = [];

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

关于计算阵列中出现频率的问题,这里有很多解决方案。考虑this one