Group and sum DateTime object by date in JavaScrip

2019-08-06 02:52发布

What is the best way to group objects by date and add them all up to create a single JavaScript object? I prefer code readability and lesser lines of code over performance as the application is not data intensive. Moreover there are going to be lots people who are going to make changes after I'm done with my internship.

Here is some sample data

[
    {"Timestamp":"Thu, 01 Jan 2015 00:57:00 GMT","cp":2,"pc":2},
    {"Timestamp":"Thu, 01 Jan 2015 01:57:00 GMT","cp":0,"pc":4},
    {"Timestamp":"Thu, 01 Jan 2015 02:57:00 GMT","cp":2,"pc":2},
    {"Timestamp":"Thu, 01 Jan 2015 03:57:00 GMT","cp":0,"pc":4},

    {"Timestamp":"Thu, 02 Jan 2015 00:57:00 GMT","cp":2,"pc":2},
    {"Timestamp":"Thu, 02 Jan 2015 01:57:00 GMT","cp":0,"pc":4},
    {"Timestamp":"Thu, 02 Jan 2015 02:57:00 GMT","cp":2,"pc":2},
    {"Timestamp":"Thu, 02 Jan 2015 03:57:00 GMT","cp":0,"pc":4}

]

I want to create this out of the above data.

[ {"Date":"2015-01-01", "cp":4, "pc":12}, {"Date":"2015-01-02", "cp":4, "pc"12} ]

If you notice, the resultant JavaScript object is the sum total of all the columns on that particular date and replace timestamp by date.

We already use moment.js in the application, so I have it at disposal. If you think moment can solve the problem in a neater fashion, please let me know.

3条回答
老娘就宠你
2楼-- · 2019-08-06 03:33

Try this.

var timeArray=[
    {"Timestamp":"Thu, 01 Jan 2015 00:57:00 GMT","cp":2,"pc":2},
    {"Timestamp":"Thu, 01 Jan 2015 01:57:00 GMT","cp":0,"pc":4},
    {"Timestamp":"Thu, 01 Jan 2015 02:57:00 GMT","cp":2,"pc":2},
    {"Timestamp":"Thu, 01 Jan 2015 03:57:00 GMT","cp":0,"pc":4},

    {"Timestamp":"Thu, 02 Jan 2015 00:57:00 GMT","cp":2,"pc":2},
    {"Timestamp":"Thu, 02 Jan 2015 01:57:00 GMT","cp":0,"pc":4},
    {"Timestamp":"Thu, 02 Jan 2015 02:57:00 GMT","cp":2,"pc":2},
    {"Timestamp":"Thu, 02 Jan 2015 03:57:00 GMT","cp":0,"pc":4}
]

var object = {}, resultArray = [];

for (var i = 0; i < timeArray.length; i++) {
    var date = timeArray[i].Timestamp;
    var localDateString = new Date(date).getFullYear() + '-' + (new Date(date).getMonth() + 1) + '-' + new Date(date).getDate();
    if (object[localDateString]) {
        object[localDateString].cp += timeArray[i].cp;
        object[localDateString].pc += timeArray[i].pc;
    } else {
        timeArray[i].Date = localDateString;
        delete timeArray[i].Timestamp;
        object[localDateString] = timeArray[i];
    }
}

for (var prop in object)
    resultArray.push(object[prop]);

console.log(resultArray);
查看更多
淡お忘
3楼-- · 2019-08-06 03:37
  • Iterate your array of objects ($.each() function can be used to iterate over any collection.)
  • Convert UTC format date string to ISO format using toISOString() method.
  • Maintain common array for date so that you can easily map your repeated date location using indexOf() method.

Here is the Code:

var arr = [
  {"Timestamp":"Thu, 01 Jan 2015 00:57:00 GMT","cp":2,"pc":2},
  {"Timestamp":"Thu, 01 Jan 2015 01:57:00 GMT","cp":0,"pc":4},
  {"Timestamp":"Thu, 01 Jan 2015 02:57:00 GMT","cp":2,"pc":2},
  {"Timestamp":"Thu, 01 Jan 2015 03:57:00 GMT","cp":0,"pc":4},

  {"Timestamp":"Thu, 02 Jan 2015 00:57:00 GMT","cp":2,"pc":2},
  {"Timestamp":"Thu, 02 Jan 2015 01:57:00 GMT","cp":0,"pc":4},
  {"Timestamp":"Thu, 02 Jan 2015 02:57:00 GMT","cp":2,"pc":2},
  {"Timestamp":"Thu, 02 Jan 2015 03:57:00 GMT","cp":0,"pc":4}
];
var resultArr = [];
var dateArr = [];   

$.each(arr, function () {
// Easiest way to get your required date format
   var date = new Date(this.Timestamp).toISOString().replace(/T/, ' ').split(' ')[0];
   var index = dateArr.indexOf(date);
   if (index == -1) {
       dateArr.push(date);
       var obj = {Date: date, cp: this.cp, pc: this.pc};
       resultArr.push(obj);
   } 
   else {
       resultArr[index].cp += this.cp;
       resultArr[index].pc += this.pc;
   }
});
console.log(resultArr); // [ {"Date":"2015-01-01", "cp":4, "pc":12}, {"Date":"2015-01-02", "cp":4, "pc"12} ]

Hope this may helpful for you.

查看更多
家丑人穷心不美
4楼-- · 2019-08-06 03:37

I believe a simple utility library such as Underscore.js or Lodash could do the job, however, this looks like a task plain old vanilla Javascript can take on by itself.

Check out the Array.prototype.map function, or probably better yet an Array.prototype.sort that takes in a sorting function applying logic to a given object's .Timestamp property.

Edit: something like

yourArray.sort(function(objA, objB){
  return objA.Timestamp > objB.TimeStamp ? -1 : 1;
});

may work.

EDIT: I see now you are trying to merge dates. In that case, I would say Array.prototype.map chained with Array.prototype.reduce is a possible path to go down. You could also (messily) use Array.prototype.filter to push all arrays of a given date into a single array, and so on for each date.

Edit:

How about a reduce, then?

var thingYouWant = yourArray.reduce(function(summed, current){
    date = changeIntoOnlyDayDate(current.Timestamp);
    var found = false;
    summed.forEach(function(obj){
        if(obj.Timestamp === date){ obj.cp++; found = true;};
    }
    if(!found){summed.push(turnThisDateIntoDesiredObject(date))}

    }
    return summed;
    }, []); 
查看更多
登录 后发表回答