10

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

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

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

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

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

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

4

4 回答 4

16

这看起来是个map reduce问题。高级解决方案如下:

  1. 重新组织列表的成员。
  2. 数一数。

以下是实现此目的的分步操作方法:

地图

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

这些现在按月-年分组。

例子:

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

减少

  1. 遍历包含列表字典的新对象。
  2. 计算每个字典列表的长度。
  3. 用作count键和列表长度作为其值。

例子:

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
}

生成的 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.

参考:

对于javascript 中的mapreduce函数,请参见 underscore.js: http:
//underscorejs.org/#map
http://underscorejs.org/#reduce

Javascript 日期对象:
https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

有关日期和日期时间对象的更多信息:
https ://en.wikipedia.org/wiki/ISO_8601

有关更多信息map reduce
https ://en.wikipedia.org/wiki/MapReduce

于 2013-07-25T14:36:00.147 回答
1

使用 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); 
于 2013-07-26T04:29:23.047 回答
0

也许这会有用

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

于 2013-07-25T14:18:14.843 回答
-1

优化解决方案

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"])
}

const GroupBy = (elem) => {
       
       dateObj = new Date(elem) 

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

  } 
于 2021-05-30T21:29:29.907 回答