Skip to content Skip to sidebar Skip to footer

How Can I Group An Array Of Objects By Month?

I'm using JavaScript. I have an array that contains data in this format: [ {'USER_NAME':'User1','LAST_SUCCESSFUL_CONNECT':'1373978337642'}, {'USER_NAME':'User2','LA

Solution 1:

This looks like a mapreduce 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 objectvar 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 herereturn 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 montho['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/#maphttp://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 mapreduce: https://en.wikipedia.org/wiki/MapReduce

Solution 2:

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 = newDate(newNumber(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); 

Solution 3:

maybe this will be useful

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

Solution 4:

optimized solution

var map_month= {}  
const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
];

for (const x of o) {
          
   GroupBy(x["LAST_SUCCESSFUL_CONNECT"])
}

constGroupBy = (elem) => {
       
       dateObj = newDate(elem) 

       monthObj = monthNames[dateObj.getMonth()] + " " + dateObj.getFullYear()
       if(map_month[monthObj]===undefined)
          map_month[monthObj+""]  = 1;
       else map_month[monthObj] += 1;

  } 

Post a Comment for "How Can I Group An Array Of Objects By Month?"