How can I group an array of objects by month?

旧巷老猫 提交于 2019-12-01 03:56:35

This looks like a map reduce problem. The high-level solution is as follows:

  1. Re-organize the members of the list.
  2. Count them.

Here is a step-by-step how-to for achieving this:

Map

  1. Iterate through the list of dictionaries
  2. Convert datetime string to javascript datetime object.
  3. Use month-year as key and list of dictionaries as value.

These are now grouped by month-year.

Example:

var l = [...];
var o = {};
var f = function(x){
    var dt_object = Date(x["LAST_SUCCESSFUL_CONNECT"]); // convert to datetime object
    var key = dt_object.year + '-' + dt_object.month;

    if (o[key] === undefined) {
        var o[key] = [];
    };

    o[key].push(x)
}

_.map(l, f(x)) //apply f to each member of l

Reduce

  1. Iterate through the new object containing dictionaries of lists.
  2. Calculate length of each dictionary's list.
  3. Use count as key and length of list as its value.

Example:

var g = function(member_count){
    //extra logic may go here
    return member_count
}

for member in o {
    count = _.reduce(l, g(member))
    member['count'] = count
}

Resulting API

o['month-year'] //for list of dictionaries in that month
o['month-year']['count'] //for the count of list of dictionaries in that month.

References:

For map and reduce functions in javascript see underscore.js:
http://underscorejs.org/#map
http://underscorejs.org/#reduce

Javascript Date object:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

For more information on Date and DateTime objects:
https://en.wikipedia.org/wiki/ISO_8601

For more information on map reduce:
https://en.wikipedia.org/wiki/MapReduce

Use Map-reduce. Here is one example using underscore.js. It is very simple though it is a bit verbose.

var data = [{
    "USER_NAME": "User1",
        "LAST_SUCCESSFUL_CONNECT": "1373978337642"
}, {
    "USER_NAME": "User2",
        "LAST_SUCCESSFUL_CONNECT": "1374515704026"
}, {
    "USER_NAME": "User3",
        "LAST_SUCCESSFUL_CONNECT": "1374749782479"
}, {
    "USER_NAME": "User4",
        "LAST_SUCCESSFUL_CONNECT": "1274749702479"
}];

var monthNames = ["January", "February", "March", "April", "May", "June",
    "July", "August", "September", "October", "November", "December"];

var map_result = _.map(data, function (item) {
    var d = new Date(new Number(item.LAST_SUCCESSFUL_CONNECT));
    var month = monthNames[d.getMonth()] + ", " + d.getFullYear();
    return {
        "Month": month,
        "User_Count": 1
    };
});

var result_temp = _.reduce(map_result, function (memo, item) {
    if (memo[item.Month] === undefined) {
        memo[item.Month] = item.User_Count;
    }else{
        memo[item.Month] += item.User_Count;
    }
    return memo;
},{});

//then wrap the result to the format you expected.
var result = _.map(result_temp, function(value, key){
    return {
        "Month": key,
        "User_Count": value
    };
});

console.log(result); 

maybe this will be useful

LINQ for JavaScript
http://linqjs.codeplex.com/

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!