3

I try to sum all "Menge" and "Fehler" values if the "Datum" is the same. The probelmm is that "Datum" is a date object.

var arr = [{"Datum":{"date":"2000-01-01 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"123","Menge":100,"Fehler":5},{"Datum":{"date":"2000-01-01 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"123","Menge":5,"Fehler":1},{"Datum":{"date":"2000-01-01 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"123","Menge":6,"Fehler":65},{"Datum":{"date":"2000-01-01 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"222","Menge":10,"Fehler":5},{"Datum":{"date":"2000-01-02 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"444","Menge":29,"Fehler":1},{"Datum":{"date":"2000-01-02 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"123","Menge":1,"Fehler":1}]

console.log(arr)
var holder = {};

arr.forEach(function (d) {
    if (holder.hasOwnProperty(d.Datum)) {
        holder[d.Datum] = holder[d.Datum] + d.Menge;
    } else {
        holder[d.Datum] = d.Menge;
    }
});

var obj2 = [];

for (var prop in holder) {
    obj2.push({
        Datum: prop,
        Menge: holder[prop]
    });
}

console.log(obj2);

But the result should be:

[
  {
    "Datum": "2000-01-01",
    "Menge": 121,
    "Fehler": 76
  },
  {
    "Datum": "2000-01-02",
    "Menge": 30,
    "Fehler": 2
  }
]
InFlames82
  • 493
  • 6
  • 17

5 Answers5

1

If you ignore the timezone and the time part, you can just extract the date part as below and use it as the key for holder.

var arr = [{"Datum":{"date":"2000-01-01 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"123","Menge":100,"Fehler":5},{"Datum":{"date":"2000-01-01 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"123","Menge":5,"Fehler":1},{"Datum":{"date":"2000-01-01 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"123","Menge":6,"Fehler":65},{"Datum":{"date":"2000-01-01 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"222","Menge":10,"Fehler":5},{"Datum":{"date":"2000-01-02 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"444","Menge":29,"Fehler":1},{"Datum":{"date":"2000-01-02 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"123","Menge":1,"Fehler":1}]

var holder = {};

arr.forEach(function (d) {
const dateStr = d.Datum.date.substring(0, 10);

  if (holder.hasOwnProperty(dateStr)) {
    var existing = holder[dateStr];
    holder[dateStr] = {
        Datum: dateStr,
        Menge: existing.Menge + d.Menge,
        Fehler: existing.Fehler + d.Fehler,
    };
  } else {
    holder[dateStr] = {
        Datum: dateStr,
        Menge: d.Menge,
        Fehler: d.Fehler,
    };
  }
});

var obj2 = Object.values(holder);
console.log(obj2);
Udith Gunaratna
  • 2,091
  • 1
  • 13
  • 17
1

Alternative way;

var arr = [{"Datum":{"date":"2000-01-01 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"123","Menge":100,"Fehler":5},{"Datum":{"date":"2000-01-01 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"123","Menge":5,"Fehler":1},{"Datum":{"date":"2000-01-01 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"123","Menge":6,"Fehler":65},{"Datum":{"date":"2000-01-01 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"222","Menge":10,"Fehler":5},{"Datum":{"date":"2000-01-02 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"444","Menge":29,"Fehler":1},{"Datum":{"date":"2000-01-02 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"123","Menge":1,"Fehler":1}]

var Arrr = [];

arr.forEach(function (d) {
var dateArr = d.Datum.date.split(" ");
if(Arrr.find(x=> x.Datum ===dateArr[0]))
{
    Arrr.find(x=> x.Datum ===dateArr[0]).Fehler += d.Fehler;
    Arrr.find(x=> x.Datum ===dateArr[0]).Menge += d.Menge;
}
else {
    Arrr.push({
        Datum: dateArr[0],
        Menge: d.Menge,
        Fehler:d.Fehler
    });
}
});

console.log(Arrr);
cacalonga
  • 11
  • 4
1

Kind of ES6 way and grouping by hash solution:

const arr = [{"Datum":{"date":"2000-01-01 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"123","Menge":100,"Fehler":5},{"Datum":{"date":"2000-01-01 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"123","Menge":5,"Fehler":1},{"Datum":{"date":"2000-01-01 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"123","Menge":6,"Fehler":65},{"Datum":{"date":"2000-01-01 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"222","Menge":10,"Fehler":5},{"Datum":{"date":"2000-01-02 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"444","Menge":29,"Fehler":1},{"Datum":{"date":"2000-01-02 00:00:00.000000","timezone_type":3,"timezone":"Europe/Berlin"},"Material":"123","Menge":1,"Fehler":1}]

const result = Object.values(arr.reduce((acc, obj) => {
  const [Datum] = obj.Datum.date.split(' ');
  const Menge = (acc[Datum]?.Menge + obj.Menge) || obj.Menge;
  const Fehler = (acc[Datum]?.Fehler + obj.Fehler) || obj.Fehler;
  const Ratio = Fehler / Menge;
  acc[Datum] = { Datum, Menge, Fehler, Ratio };
  return acc;
}, {}));

console.log(result);
.as-console-wrapper{min-height: 100%!important; top: 0}
A1exandr Belan
  • 4,442
  • 3
  • 26
  • 48
  • thank you. an additional question: How do I create additional to "Menge" and "Fehler" an new key "ratio" where I calculate the ratio of Fehler/Menge? I don't know how to access Menge and Fehler values in your code to calculate the ratio. – InFlames82 Jan 13 '22 at 12:43
  • @InFlames82 Happy to help! Check updated code with ratio property – A1exandr Belan Jan 13 '22 at 12:59
  • Thank you! But I have one more question. How do I calculate the values when not only "Datum" but a second key must match? For example "Datum" and "Material" must be the same? – InFlames82 Jan 14 '22 at 07:28
  • @InFlames82 You can extend the hash to group by multiple fields. Look at this [answer](https://stackoverflow.com/a/70665136/87713) for example. This solution filters the array by two criteria, but approach will be the same. – A1exandr Belan Jan 14 '22 at 07:48
  • I create a new question for this. https://stackoverflow.com/q/70708103/10474530 – InFlames82 Jan 14 '22 at 08:54
  • @InFlames82 you can accept Nina Scholz's answer, it is the best one. – A1exandr Belan Jan 14 '22 at 09:18
0

Alternative, if your timezone has influence, you can stringify your Datum, like this:

var arr = [{ "Datum": { "date": "2000-01-01 00:00:00.000000", "timezone_type": 3, "timezone": "Europe/Berlin" }, "Material": "123", "Menge": 100, "Fehler": 5 }, { "Datum": { "date": "2000-01-01 00:00:00.000000", "timezone_type": 3, "timezone": "Europe/Berlin" }, "Material": "123", "Menge": 5, "Fehler": 1 }, { "Datum": { "date": "2000-01-01 00:00:00.000000", "timezone_type": 3, "timezone": "Europe/Berlin" }, "Material": "123", "Menge": 6, "Fehler": 65 }, { "Datum": { "date": "2000-01-01 00:00:00.000000", "timezone_type": 3, "timezone": "Europe/Berlin" }, "Material": "222", "Menge": 10, "Fehler": 5 }, { "Datum": { "date": "2000-01-02 00:00:00.000000", "timezone_type": 3, "timezone": "Europe/Berlin" }, "Material": "444", "Menge": 29, "Fehler": 1 }, { "Datum": { "date": "2000-01-02 00:00:00.000000", "timezone_type": 3, "timezone": "Europe/Berlin" }, "Material": "123", "Menge": 1, "Fehler": 1 }]

var holder = new Map();

arr.forEach(function (d) {
  const strDatum = JSON.stringify(d.Datum);
  const current = holder.get(strDatum) || { Menge: 0, Fehler: 0};

  holder.set(strDatum, { Menge: current.Menge + d.Menge, Fehler: current.Fehler + d.Fehler });
});

var obj2 = [];

holder.forEach((value, key) => {
  obj2.push({
    Datum: JSON.parse(key),
    Menge: value.Menge,
    Fehler: value.Fehler,
  });
});

console.log(obj2);
PZBird
  • 321
  • 2
  • 8
0

Without Using JS split() or substring()

Use Date() to get your defined results. I have just a suggestion on top of Udith answer. You can do some thing like this:

// This can easily give you the results without even worrying for any substring stuff
const date = new Date(obj.Datum.date)

Final Code:

var dataArray = [{ "Datum": { "date": "2000-01-01 00:00:00.000000", "timezone_type": 3, "timezone": "Europe/Berlin" }, "Material": "123", "Menge": 100, "Fehler": 5 }, { "Datum": { "date": "2000-01-01 00:00:00.000000", "timezone_type": 3, "timezone": "Europe/Berlin" }, "Material": "123", "Menge": 5, "Fehler": 1 }, { "Datum": { "date": "2000-01-01 00:00:00.000000", "timezone_type": 3, "timezone": "Europe/Berlin" }, "Material": "123", "Menge": 6, "Fehler": 65 }, { "Datum": { "date": "2000-01-01 00:00:00.000000", "timezone_type": 3, "timezone": "Europe/Berlin" }, "Material": "222", "Menge": 10, "Fehler": 5 }, { "Datum": { "date": "2000-01-02 00:00:00.000000", "timezone_type": 3, "timezone": "Europe/Berlin" }, "Material": "444", "Menge": 29, "Fehler": 1 }, { "Datum": { "date": "2000-01-02 00:00:00.000000", "timezone_type": 3, "timezone": "Europe/Berlin" }, "Material": "123", "Menge": 1, "Fehler": 1 }];

const holder = {};

dataArray.forEach(obj => {
  // Using Date() of Javascript for converting the timestamp to a 
  // a date object for better computation
  const objDate = new Date(obj.Datum.date);
  if(holder.hasOwnProperty(objDate)){
    let existingData = holder[objDate];
    holder[objDate] = {
        Datum: obj.Datum.date,
        Menge: existingData.Menge + obj.Menge,
        Fehler: existingData.Fehler + obj.Fehler
    };
  }else{
    holder[objDate] = {
      Datum: obj.Datum.date,
      Menge: obj.Menge,
      Fehler: obj.Fehler
    }
  }
});

const resultObj = Object.values(holder);
console.log(resultObj);
Alok
  • 8,452
  • 13
  • 55
  • 93