javascript 如何按月对一组对象进行分组?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17860382/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 09:53:20  来源:igfitidea点击:

How can I group an array of objects by month?

javascriptcountgroup-bydate-range

提问by Perspectivus

I'm using JavaScript. I have an array that contains data in this format:

我正在使用 JavaScript。我有一个包含以下格式数据的数组:

[
        {"USER_NAME":"User1","LAST_SUCCESSFUL_CONNECT":"1373978337642"},
        {"USER_NAME":"User2","LAST_SUCCESSFUL_CONNECT":"1374515704026"},
        {"USER_NAME":"User3","LAST_SUCCESSFUL_CONNECT":"1374749782479"}
]

(the numbers above represent UTC date/time in milliseconds.

(以上数字以毫秒为单位表示 UTC 日期/时间。

I would like to group (count) the data by month. Something like this:

我想按月对数据进行分组(计数)。像这样的东西:

[
    {"Month":"January, 2014","User_Count": 2},
    {"Month":"February, 2014","User_Count": 1},
]

I could use jQueryif it simplifies matters.

如果可以简化问题,我可以使用jQuery

回答by pygeek

This looks like a mapreduceproblem. The high-level solution is as follows:

这看起来有mapreduce问题。高层解决方案如下:

  1. Re-organize the members of the list.
  2. Count them.
  1. 重新组织名单的成员。
  2. 数一数他们。

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.
  1. 遍历字典列表
  2. 将日期时间字符串转换为 javascript 日期时间对象。
  3. 使用月-年作为键,字典列表作为值。

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 countas key and length of list as its value.
  1. 遍历包含列表字典的新对象。
  2. 计算每个字典列表的长度。
  3. 使用count的列表作为其价值的关键和长度。

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

结果 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 mapand reducefunctions in javascript see underscore.js:
http://underscorejs.org/#map
http://underscorejs.org/#reduce

对于mapreduce在javascript见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

Javascript 日期对象: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

有关 Date 和 DateTime 对象的更多信息:https:
//en.wikipedia.org/wiki/ISO_8601

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

有关更多信息mapreducehttps:
//en.wikipedia.org/wiki/MapReduce

回答by zs2020

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

使用 Map-reduce。这是一个使用 underscore.js 的示例。虽然有点冗长,但它非常简单。

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

回答by svillamayor

maybe this will be useful

也许这会有用

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

用于 JavaScript 的 LINQ
http://linqjs.codeplex.com/