按键分组数组,然后求和

时间:2018-08-23 20:39:15

标签: javascript

我试图操纵一个数据数组,以便按一个键对它进行分组,然后包含一个属性,该属性显示每个组的总数,以及所有组的总数,但是我遇到了麻烦。

这是我开始使用的数据:

[ 
  {paren: 'abc', details: '', value: 100},
  {paren: 'abc', details: '', value: 120},
  {paren: 'vav', details: '', value: 400},
  {paren: 'aol', details: '', value: 40},
  {paren: 'ckk', details: '', value: 400},
  {paren: 'vav', details: '', value: 20}
]

这就是我想要结束的。总数是一个组中所有对象的价值之和,grandTotal是所有组之和。

const groupings = {
  grandTotal: 1080,
  groupings: [
    {
      group: 'abc', 
      data: [      
        {paren: 'abc', details: '', value: 100},
        {paren: 'abc', details: '', value: 120},
      ],
      total: 220
    },

    {
      group: 'vav', 
      data: [      
        {paren: 'vav', details: '', value: 400},
        {paren: 'vav', details: '', value: 20}
      ],
      total: 420
    },

    {
      group: 'aol', 
      data: [      
        {paren: 'aol', details: '', value: 40},
      ],
      total: 40
    },

    {
      group: 'ckk', 
      data: [      
        {paren: 'ckk', details: '', value: 400},
      ],
      total: 400
    },
  ]
};

我一直试图通过reduce / map的组合来做到这一点,而且我已经很接近了。我唯一无法弄清楚的是如何有效地进行总计。这是我的代码:

const mapGroups = array.reduce((obj, item) => {
  obj[item.paren] = obj[item.paren] || [];
  obj[item.paren].push(item);
  return obj;
}, {});

return Object.keys(mapGroups).map((key) => {
  return {group: key, data: mapGroups[key]};
});

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

将具有整个结构的对象传递给reduce。然后,您可以在循环过程中更新嵌套对象。这样您就可以将每个运行总计和总计添加到其中。

最后,最后您可以将groupings对象替换为其值的数组。

const array = [ 
  {paren: 'abc', details: '', value: 100},
  {paren: 'abc', details: '', value: 120},
  {paren: 'vav', details: '', value: 400},
  {paren: 'aol', details: '', value: 40},
  {paren: 'ckk', details: '', value: 400},
  {paren: 'vav', details: '', value: 20}
];

const mapGroups = array.reduce((obj, item) => {
  obj.groupings[item.paren] = obj.groupings[item.paren] || {
    group: item.paren,
    data: [],
    total: 0
  };
  obj.groupings[item.paren].data.push(item);
  obj.groupings[item.paren].total += item.value;
  obj.grandTotal += item.value;
  return obj;
}, {grandTotal: 0, groupings: {}});

mapGroups.groupings = Object.values(mapGroups.groupings);
console.log(mapGroups);