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

5 Answers 5

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}

Sign up to request clarification or add additional context in comments.

6 Comments

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 Happy to help! Check updated code with ratio property
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 You can extend the hash to group by multiple fields. Look at this answer for example. This solution filters the array by two criteria, but approach will be the same.
I create a new question for this. stackoverflow.com/q/70708103/10474530
|
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);

2 Comments

Thank you! But what about the "Fehler" sum? You can see it in my example result.
Updated the code to include "Fehler" sum and also removed the need for 2nd loop
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);

Comments

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

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.