Gruppieren und summieren Sie und generieren Sie ein Objekt für jedes Array in JavaScript

Lesezeit: 3 Minuten

Benutzer-Avatar
Fernando

Ich muss nach ID und Summe gruppieren, aber ich brauche für jedes Ergebnis ein neues Objekt:

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

Ich habe diesen Code, der nur ein Objekt mit dem Ergebnis zurückgibt

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

Aber ich brauche sowas:

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

Wie kann ich es tun?

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

  • Ich verstehe nicht, warum Sie den Code von geändert haben reduce. Das Einzige, was zählte, war Object.keys(map).map(id => map[id])

    – Ibrahim Mahrir

    14. Mai 2018 um 20:16 Uhr


  • @ibrahimmahrir Ich habe nicht verstanden, was du sagen willst. Ist es schlecht?

    – Zohaib Ijaz

    14. Mai 2018 um 20:18 Uhr

  • @ZohaibIjaz Nein nein. Ich wollte sagen, dass die reduce Codeänderung war irrelevant. Ihre Antwort hätte so kurz sein können wie: Tun result = Object.keys(map).map(id => map[id]);ohne umschreiben zu müssen reduce Code.

    – Ibrahim Mahrir

    14. Mai 2018 um 20:24 Uhr

  • @ibrahimmahrir Nein, das wird keine richtige Antwort sein. Wir müssen uns gruppieren id und Summe total Werte. Reduzieren ist also erforderlich

    – Zohaib Ijaz

    14. Mai 2018 um 20:29 Uhr

Sie können dies versuchen:

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

  • was bedeutet das ‘?’ und das ‘:’ bedeuten?

    – BreadBoard.ini

    16. Juli 2021 um 17:00 Uhr

  • @BreadBoard.ini ist als ternärer Operator bekannt. Im Grunde ist es eine Inline-If-Else-Bedingung. Hier können Sie mehr darüber lesen developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

    – Aravindan Ve

    18. Juli 2021 um 18:35 Uhr

Ändere dein reduce zu:

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

Beispiel:

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

  • Das hat mir wirklich geholfen, danke 🙂 Sehr einfaches und detailliertes Beispiel

    – vivasuzi

    27. Januar 2021 um 4:04 Uhr

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
}

1015180cookie-checkGruppieren und summieren Sie und generieren Sie ein Objekt für jedes Array in JavaScript

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy