2013-07-25 10 views
5

Ich benutze JavaScript. Ich habe ein Array, das Datum in diesem Format enthält:Wie kann ich ein Array von Objekten nach Monat gruppieren?

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

(die Zahlen oben darstellen UTC-Datum/Zeit in Millisekunden

Ich mag Gruppe (count) die Daten von Monat Etwas Ähnliches.. :

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

ich jQuery verwenden könnte, wenn es Dinge vereinfacht

+2

Wird dieses Objekt von einem Server zurückgegeben? Wenn dem so ist, würde ich empfehlen, die Daten im richtigen Format an den Client zu senden, anstatt die Analyselogik in Java-Script hinzuzufügen. Es ist normalerweise einfacher und mehr Einheiten testbar, um diese Art von Logik auf dem Server auszuführen. – TGH

+0

Ja, ich bekomme die Daten von einem Server in [oData] (http://www.odata.org/). Das bedeutet, dass ich möglicherweise nicht einmal den Servercode ändern muss, sondern stattdessen oDatas "$ count" -Option verwenden muss (ich bin mir nicht sicher, ob dies mir das geben würde, was ich möchte). Ich habe jedoch bereits die Rohdaten im Client von einer vorherigen Abfrage, und ich möchte die Hin-und Rückfahrt speichern. – Perspectivus

+0

Bitte markieren Sie diese Frage als beantwortet, wenn meine Antwort unten tatsächlich zufriedenstellend ist. Ansonsten, ausführlich. – pygeek

Antwort

10

Das sieht wie ein mapreduce Problem. Die High-Level-Lösung ist wie folgt:

  1. Organisieren Sie die Mitglieder der Liste.
  2. Zählen Sie sie.

Hier ist ein Schritt-für-Schritt, wie zu dies zu erreichen:

Karte

  1. Iterate durch die Liste der Wörterbücher
  2. konvertieren Datetime-Zeichenfolge in Javascript-Datetime-Objekt .
  3. Verwenden Sie Monat-Jahr als Schlüssel und Liste der Wörterbücher als Wert.

Diese sind jetzt nach Monat-Jahr gruppiert.

Beispiel:

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 durch das neue Objektwörterbuch von Listen enthält.
  2. Berechnen Sie die Länge der Liste jedes Wörterbuchs.
  3. Verwenden Sie count als Schlüssel und Länge der Liste als Wert.

Beispiel:

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 
} 

Resultierende 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. 

Referenzen:

Für map und reduce fu nktionen in Javascript sehen Underscore.js:
http://underscorejs.org/#map
http://underscorejs.org/#reduce

Javascript Date-Objekt:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

Weitere Informationen über Datum und Datetime-Objekte:
https://en.wikipedia.org/wiki/ISO_8601

Weitere Informationen über mapreduce:
https://en.wikipedia.org/wiki/MapReduce

+0

Dank @pygeek für Ihre ausführliche Antwort. Ich kann keine Open-Source- oder Drittanbieter-Quellen außer jQuery verwenden, daher ist Unterstreichung für mich out. Ich werde jQuerys Map und JavaScript's Array reduzieren. – Perspectivus

1

Verwenden Sie Map-reduce. Hier ist ein Beispiel mit der Verwendung von underscore.js. Es ist sehr einfach, obwohl es ein bisschen ausführlich ist.

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