2013-07-25 33 views
5

Tôi đang sử dụng JavaScript. Tôi có một mảng chứa dữ liệu ở định dạng này:Làm cách nào để nhóm một mảng các đối tượng theo tháng?

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

(những con số trên đại diện cho ngày UTC/thời gian trong mili giây

Tôi muốn nhóm (count) các dữ liệu bằng cách Something như thế này tháng.. :

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

tôi có thể sử dụng jQuery nếu nó đơn giản hoá vấn đề

+2

Đối tượng này có được trả về từ máy chủ không? Nếu vậy tôi khuyên bạn nên trả lại dữ liệu theo đúng định dạng cho máy khách, thay vì thêm phân tích cú pháp logic vào tập lệnh java. Nó thường dễ dàng hơn và nhiều đơn vị kiểm tra để chạy loại logic trên máy chủ. – TGH

+0

Có, tôi đang nhận dữ liệu từ máy chủ trong [oData] (http://www.odata.org/). Điều này có nghĩa là tôi có thể thậm chí không phải thay đổi mã máy chủ, nhưng thay vì sử dụng tùy chọn '$ count' của oData (tôi không chắc chắn điều này sẽ cho tôi những gì tôi muốn). Tuy nhiên, tôi đã có dữ liệu thô trong ứng dụng từ một truy vấn trước đó và tôi muốn lưu chuyến đi khứ hồi. – Perspectivus

+0

Vui lòng đánh dấu câu hỏi này là đã trả lời nếu câu trả lời của tôi dưới đây thực sự đạt yêu cầu. Nếu không, phức tạp. – pygeek

Trả lời

10

này trông giống như một vấn đề mapreduce. Giải pháp cấp cao như sau:

  1. Sắp xếp lại các thành viên của danh sách.
  2. Đếm chúng.

Đây là một bước-by-step cách để để đạt được điều này:

Bản đồ

  1. Duyệt qua danh sách các từ điển
  2. Chuyển đổi chuỗi datetime để javascript đối tượng datetime .
  3. Sử dụng tháng năm làm khóa và danh sách từ điển làm giá trị.

Bây giờ, chúng được nhóm theo tháng.

Ví dụ:

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 

Giảm

  1. Duyệt qua các đối tượng mới có chứa các từ điển của danh sách.
  2. Tính toán độ dài của từng danh sách từ điển.
  3. Sử dụng count làm khóa và độ dài của danh sách làm giá trị của nó.

Ví dụ:

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 
} 

Kết quả 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. 

Tài liệu tham khảo:

Đối mapreduce fu nctions trong javascript thấy underscore.js:
http://underscorejs.org/#map
http://underscorejs.org/#reduce

Javascript ngày đối tượng:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

Để biết thêm thông tin về ngày và DateTime đối tượng:
https://en.wikipedia.org/wiki/ISO_8601

Để biết thêm thông tin về mapreduce:
https://en.wikipedia.org/wiki/MapReduce

+0

Cảm ơn @pygeek vì câu trả lời phức tạp của bạn. Tôi không thể sử dụng nguồn mở hoặc các nguồn của bên thứ 3 ngoài jQuery, vì vậy các gạch dưới không phù hợp với tôi. Tôi sẽ sử dụng bản đồ của jQuery và Array của JavaScript giảm. – Perspectivus

1

Sử dụng Map-reduce. Dưới đây là một ví dụ sử dụng underscore.js. Nó rất đơn giản mặc dù nó là một chút tiết.

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); 
Các vấn đề liên quan