2013-07-25 67 views
5

我正在使用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如果它簡化事項

+2

該對象是否從服務器返回?如果是這樣,我會建議以正確的格式將數據返回給客戶端,而不是在java腳本中添加解析邏輯。在服務器上運行這種類型的邏輯通常更容易,更容易測試。 – TGH

+0

是的,我從[oData](http://www.odata.org/)中的服務器獲取數據。這意味着我可能甚至不需要更改服務器代碼,而是使用oData的'$ count'選項(我不確定這會給我什麼我想要的)。但是,我已經從先前的查詢中獲得了客戶端中的原始數據,並且我想保存往返行程。 – Perspectivus

+0

如果我的回答確實令人滿意,請將此問題標記爲已回答。否則,精心製作。 – pygeek

回答

10

這看起來像一個mapreduce問題。高級解決方案如下:

  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. 

參考文獻:

對於mapreduce福在JavaScript nctions看到underscore.js:
http://underscorejs.org/#map
http://underscorejs.org/#reduce

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

有關日期和DateTime對象的詳細信息:
https://en.wikipedia.org/wiki/ISO_8601

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

+0

感謝@pygeek爲您精心製作的答案。我不能使用jQuery以外的開源或第三方來源,所以underscorejs對我來說是不適合的。我將使用jQuery的地圖和JavaScript的Array reduce。 – Perspectivus

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