2016-01-24 10 views
6

Ich möchte umwandeln showtimesData zu showtimesByLocationByDate

Eine Idee, wie man es ohne Verwendung von Drittanbieter-Bibliothek und nur mit reinem Javascript tun? Welche Drittanbieter-Bibliothek kann ich sonst verwenden?Wie gruppiert man ein JavaScript-Objekt-Array nach mehreren Eigenschaften?

var showtimesData = [ 
     {"location":"location1", "date":"31-12-2016", "time":"1:00"}, 
     {"location":"location1", "date":"31-12-2016", "time":"2:00"}, 
     {"location":"location1", "date":"01-01-2017", "time":"3:00"}, 
     {"location":"location1", "date":"01-01-2017", "time":"4:00"}, 
     {"location":"location2", "date":"31-12-2016", "time":"1:00"}, 
     {"location":"location2", "date":"31-12-2016", "time":"2:00"}, 
     {"location":"location2", "date":"01-01-2017", "time":"3:00"}, 
     {"location":"location2", "date":"01-01-2017", "time":"4:00"}, 
    ]; 
    var showtimesByLocationByDate = [ 
     { 
      "location":"location1", 
      "dates":[ 
       { 
        "date":"31-12-2016", 
        "times":["1:00","2:00"] 
       }, 
       { 
        "date":"01-01-2017", 
        "times":["3:00","4:00"] 
       } 
      ] 
     }, 
     { 
      "location":"location2", 
      "dates":[ 
       { 
        "date":"31-12-2016", 
        "times":["1:00","2:00"] 
       }, 
       { 
        "date":"01-01-2017", 
        "times":["3:00","4:00"] 
       } 
      ] 
     }, 
    ]; 
+0

Muss dieses spezifische Format folgen? Datumssuche wäre viel schneller, wenn es eine Eigenschaft eines Objekts wäre. – MinusFour

+0

Wenn ich die Daten als Eigenschaften festlegen soll, kann ich die Eigenschaften durchlaufen, um die Daten als Zeichenfolgen zu erhalten? – davidchoo12

+0

Ja, es ist möglich, die Eigenschaften des Objekts zu durchlaufen. – MinusFour

Antwort

4

Dieser Vorschlag bietet nur Array.prototype.reduce() mit einem temporären Objekt zur Referenzierung der Array-Elemente.

var showtimesData = [{ "location": "location1", "date": "31-12-2016", "time": "1:00" }, { "location": "location1", "date": "31-12-2016", "time": "2:00" }, { "location": "location1", "date": "01-01-2017", "time": "3:00" }, { "location": "location1", "date": "01-01-2017", "time": "4:00" }, { "location": "location2", "date": "31-12-2016", "time": "1:00" }, { "location": "location2", "date": "31-12-2016", "time": "2:00" }, { "location": "location2", "date": "01-01-2017", "time": "3:00" }, { "location": "location2", "date": "01-01-2017", "time": "4:00" }, ], 
 
    showtimesByLocationByDate = showtimesData.reduce(function (r, a) { 
 
     var o; 
 
     if (!(a.location in r.obj)) { 
 
      o = { location: a.location, dates: [] }; 
 
      r.obj[a.location] = { dates: o.dates }; 
 
      r.array.push(o); 
 
     } 
 
     if (!(a.date in r.obj[a.location])) { 
 
      o = { date: a.date, times: [] }; 
 
      r.obj[a.location].dates.push(o); 
 
      r.obj[a.location][a.date] = o.times; 
 
     } 
 
     r.obj[a.location][a.date].push(a.time); 
 
     return r; 
 
    }, { array: [], obj: {} }).array; 
 

 
document.write('<pre>' + JSON.stringify(showtimesByLocationByDate, 0, 4) + '</pre>');

Bonus: Allgemein Version mit einer bestimmten Datenstruktur

var showtimesData = [{ "location": "location1", "date": "31-12-2016", "time": "1:00" }, { "location": "location1", "date": "31-12-2016", "time": "2:00" }, { "location": "location1", "date": "01-01-2017", "time": "3:00" }, { "location": "location1", "date": "01-01-2017", "time": "4:00" }, { "location": "location2", "date": "31-12-2016", "time": "1:00" }, { "location": "location2", "date": "31-12-2016", "time": "2:00" }, { "location": "location2", "date": "01-01-2017", "time": "3:00" }, { "location": "location2", "date": "01-01-2017", "time": "4:00" }, ], 
 
    structure = [ 
 
     { key: 'location', data: 'dates' }, 
 
     { key: 'date', data: 'times' }, 
 
     { key: 'time' } 
 
    ], 
 
    showtimesByLocationByDate = showtimesData.reduce(function (r, a) { 
 
     var properties = structure.slice(), 
 
      lastKey = properties.pop().key; 
 

 
     properties.reduce(function (rr, b) { 
 
      var o = {}, 
 
       p = {}, 
 
       key = b.key, 
 
       value = a[key], 
 
       array = b.data; 
 

 
      if (!(value in rr.obj)) { 
 
       o[key] = value; 
 
       o[array] = []; 
 
       p[array] = o[array]; 
 
       rr.obj[value] = p; 
 
       rr.array.push(o); 
 
      } 
 
      return { array: rr.obj[value][array], obj: rr.obj[value] }; 
 
     }, r).array.push(a[lastKey]); 
 

 
     return r; 
 
    }, { array: [], obj: {} }).array; 
 

 
document.write('<pre>' + JSON.stringify(showtimesByLocationByDate, 0, 4) + '</pre>');

+0

Sie antworten sehr präzise, ​​aber ich frage mich nur, gibt es eine Möglichkeit, es generischer zu machen? – Rajesh

+0

@Rajesh, es hängt von der Datenstruktur ab und wie generisch es sein sollte. –

+0

Ich habe mich nur gefragt, ob wir eine Funktion erstellen könnten, bei der wir Daten und Eigenschaften an Gruppengrenzen übergeben und einen gruppierten Wert zurückgeben. Das Folgende ist das [JSFiddle] (https://jsfiddle.net/RajeshDixit/sktkjpno/), das ich bisher versucht habe. – Rajesh

4

ich diese Transformation schlagen würde:

var showtimesData = [ 
 
     {"location":"location1", "date":"31-12-2016", "time":"1:00"}, 
 
     {"location":"location1", "date":"31-12-2016", "time":"2:00"}, 
 
     {"location":"location1", "date":"01-01-2017", "time":"3:00"}, 
 
     {"location":"location1", "date":"01-01-2017", "time":"4:00"}, 
 
     {"location":"location2", "date":"31-12-2016", "time":"1:00"}, 
 
     {"location":"location2", "date":"31-12-2016", "time":"2:00"}, 
 
     {"location":"location2", "date":"01-01-2017", "time":"3:00"}, 
 
     {"location":"location2", "date":"01-01-2017", "time":"4:00"}, 
 
    ]; 
 
    
 
var transformed = showtimesData.reduce(function(obj, show){ 
 
    //var { location, date, time } = show; //if destructuring is available 
 
    var location = show.location, 
 
     date = show.date, 
 
     time = show.time, 
 
     objLocation = obj[location] = obj[location] || { dates : { } }, 
 
     dates = objLocation.dates, 
 
     date = dates[date] = dates[date] || [ ]; 
 

 
     date.push(time); 
 
     return obj; 
 
}, {}); 
 
results.innerHTML = JSON.stringify(transformed, null, '\t');
<pre id="results"></pre>

Aber wenn Sie es wirklich zu, dass zu transformieren möchten, würde ich vorschlagen, diese Transformation grabing und wo es sich auf Ihre vorgeschlagenen Struktur überein.

var showtimesData = [ 
 
     {"location":"location1", "date":"31-12-2016", "time":"1:00"}, 
 
     {"location":"location1", "date":"31-12-2016", "time":"2:00"}, 
 
     {"location":"location1", "date":"01-01-2017", "time":"3:00"}, 
 
     {"location":"location1", "date":"01-01-2017", "time":"4:00"}, 
 
     {"location":"location2", "date":"31-12-2016", "time":"1:00"}, 
 
     {"location":"location2", "date":"31-12-2016", "time":"2:00"}, 
 
     {"location":"location2", "date":"01-01-2017", "time":"3:00"}, 
 
     {"location":"location2", "date":"01-01-2017", "time":"4:00"}, 
 
    ]; 
 
    
 
var transformed = showtimesData.reduce(function(obj, show){ 
 
    //var { location, date, time } = show; //if destructuring is available 
 
    var location = show.location, 
 
     date = show.date, 
 
     time = show.time, 
 
     objLocation = obj[location] = obj[location] || { dates : { } }, 
 
     dates = objLocation.dates, 
 
     date = dates[date] = dates[date] || [ ]; 
 

 
     date.push(time); 
 
     return obj; 
 
}, {}); 
 

 
var secondTransformed = Object.keys(transformed).map(function(key){ 
 
    var dates = transformed[key].dates, 
 
     transformedDates = Object.keys(dates).map(function(key){ 
 
      return { date : key, times : dates[key] } 
 
     }); 
 
    return { location : key, dates : transformedDates } 
 
}); 
 
results.innerHTML = JSON.stringify(secondTransformed, null, '\t');
<pre id="results"></pre>

Zwar gibt es bessere Möglichkeiten, diese (Leistung klug) zu tun.

+1

Logs 'Uncaught SyntaxError: Unerwartetes Token {' an 'Konsole' – guest271314

+0

Es ist die Destrukturierungsaufgabe, die Ihr Browser noch nicht unterstützt. – MinusFour

+0

Ok, werde bei verschiedenen Browser versuchen – guest271314

Verwandte Themen