Javascript GROUPBY和sum,并为每个数组生成一个对象

Javascript GROUPBY和sum,并为每个数组生成一个对象,javascript,arrays,object,reduce,Javascript,Arrays,Object,Reduce,我需要这方面的帮助,我需要按id和sum分组,但我需要为每个结果创建一个新对象 let data =[ {"id":"2018", "name":"test", "total":1200}, {"id":"2019", "name":"wath", "total":1500}, {"id":"2019", "name":"wath", "total":1800}, {"id":"2020", "name":"zooi", "total":1000}, ] 我有一

我需要这方面的帮助,我需要按id和sum分组,但我需要为每个结果创建一个新对象

let data =[
    {"id":"2018", "name":"test", "total":1200},
    {"id":"2019", "name":"wath", "total":1500},
    {"id":"2019", "name":"wath", "total":1800},
    {"id":"2020", "name":"zooi", "total":1000},
]
我有一段代码,它只返回一个对象和结果

let result = data.reduce(function (r, o) {
    (r[o.id])?
        r[o.id] += o.total:
        r[o.id] = o.total; 
    return r;
});
但我需要一些像这样的

[
    {"id":"2018", "name":"test", "total":1200},
    {"id":"2019", "name":"wath", "total":2300},
    {"id":"2020", "name":"zooi", "total":1000},
]
有什么建议吗?谢谢
let数据=[
{“id”:“2018”,“name”:“test”,“total”:1200},
{“id”:“2019”,“name”:“wath”,“total”:1500},
{“id”:“2019”,“name”:“wath”,“total”:1800},
{“id”:“2020”,“name”:“zooi”,“total”:1000},
];
让map=data.reduce((上一页,下一页)=>{
如果(上一页中的next.id){
prev[next.id].total+=next.total;
}否则{
prev[next.id]=next;
}
返回上一个;
}, {});
让result=Object.keys(map.map)(id=>map[id]);

控制台日志(结果)将您的
减少为:

let result = data.reduce(function(acc, obj) {             // for each obj in data
    if(acc.map.hasOwnProperty(obj.id)) {                  // if the map contains an object for the current object's id
        acc.map[obj.id].total += +obj.total;              // then add the current object's total to it
    } else {                                              // otherwise
        var newObj = Object.assign({}, obj);              // create a new object (a copy of the current object)
        acc.map[obj.id] = newObj;                         // add the new object to both the map
        acc.data.push(newObj);                            // ... and the data array
    }
    return acc;
}, {data: [], map: {}}).data;                             // the accumulator should have an array for the data objects (which will be our result) and a map object which maps the ids to the objects in the data array. Once our reduce finishes its work, we assign the data array of the accumulator to result
示例:

let data=[{“id”:“2018”,“name”:“test”,“total”:1200},{“id”:“2019”,“name”:“wath”,“total”:1500},{“id”:“2019”,“name”:“wath”,“total”:1800},{“id”:“2020”,“name”:“zooi”,“total”:1000};
让结果=数据减少(功能(acc、obj){
if(根据地图hasOwnProperty(对象id)){
acc.map[obj.id]。总计+=+obj.total;
}否则{
var newObj=Object.assign({},obj);
acc.map[obj.id]=新obj;
acc.data.push(新OBJ);
}
返回acc;
},{data:[],map:{});
控制台日志(结果)您可以尝试以下方法:

const result = Object.values(data.reduce((r, o) => (r[o.id]
  ? (r[o.id].total += o.total)
  : (r[o.id] = {...o}), r), {}));

我不明白您为什么要更改
reduce
的代码。唯一重要的是
Object.keys(map).map(id=>map[id])
@ibrahimmahrir我不明白你想说什么。是坏的吗?@ZohaibIjaz不是。我的意思是说
reduce
代码更改是不相关的。你的答案可能很简单,比如说,Do
result=Object.keys(map.map)(id=>map[id]),无需重写
减少
代码。@ibrahimmahrir不,这不是正确答案。我们需要根据
id
total
值进行分组。所以减少是必需的这真的帮助了我谢谢:)非常简单和详细的例子
import uniqBy from 'lodash/uniqBy'

export function transform (array) {
  const newArray = []
  const uniq = uniqBy(array, 'id')

  uniq.forEach(item => {
    const total = array
      .filter(({id}) => item.id === id)
      .reduce((sum, current) => sum + current.total, 0)

    newArray.push({
      ...item,
      total
    })
  })

  return newArray
}