group by, and sum, and generate a object for each array javascript

做~自己de王妃 提交于 2019-12-10 09:43:30

问题


i need help with this, i need group by id and sum, but i need a new object for each 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},
]

i have this code that return just one object with the result

let result = data.reduce(function (r, o) {
    (r[o.id])?
        r[o.id] += o.total:
        r[o.id] = o.total; 
    return r;
});

but i need some like this

[
    {"id":"2018", "name":"test", "total":1200},
    {"id":"2019", "name":"wath", "total":2300},
    {"id":"2020", "name":"zooi", "total":1000},
]

any suggestion?, thanks


回答1:


You can try this:

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



回答2:


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 map = data.reduce((prev, next) =>{
  if (next.id in prev) {
    prev[next.id].total += next.total;
  } else {
     prev[next.id] = next;
  }
  return prev;
}, {});

let result = Object.keys(map).map(id => map[id]);

console.log(result);



回答3:


Change your reduce to:

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

Example:

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(acc, obj) {
    if(acc.map.hasOwnProperty(obj.id)) {
        acc.map[obj.id].total += +obj.total;
    } else {
        var newObj = Object.assign({}, obj);
        acc.map[obj.id] = newObj;
        acc.data.push(newObj);
    }
    return acc;
}, {data: [], map: {}}).data;

console.log(result);



回答4:


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
}


来源:https://stackoverflow.com/questions/50338082/group-by-and-sum-and-generate-a-object-for-each-array-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!