How Can I Group An Array Of Objects By Month?
Solution 1:
This looks like a map
reduce
problem. The high-level solution is as follows:
- Re-organize the members of the list.
- Count them.
Here is a step-by-step how-to for achieving this:
Map
- Iterate through the list of dictionaries
- Convert datetime string to javascript datetime object.
- 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
- Iterate through the new object containing dictionaries of lists.
- Calculate length of each dictionary's list.
- 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 map
reduce
:
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?"