сгруппировать, и сумма, и сгенерировать объект для каждого массива JavaScript - PullRequest
0 голосов
/ 14 мая 2018

Мне нужна помощь в этом, мне нужна группа по идентификатору и сумме, но мне нужен новый объект для каждого результата

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},
]

Любое предложение ?, спасибо

Ответы [ 4 ]

0 голосов
/ 14 мая 2018
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
}
0 голосов
/ 14 мая 2018

Измените reduce на:

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

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);
0 голосов
/ 14 мая 2018

Вы можете попробовать это:

const result = Object.values(data.reduce((r, o) => (r[o.id]
  ? (r[o.id].total += o.total)
  : (r[o.id] = {...o}), r), {}));
0 голосов
/ 14 мая 2018

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