2016-04-18 3 views
3

ich derzeit lodash und moment.js lerne bekommen, und ich bin ein Dummy-Daten.Verfahren Dummy-Daten verwenden, die eine Liste von 1000 doctors.I enthalten hat damit begonnen, die Arbeit mit Array.prototype.map() und Array.prototype.filter() und werden sie bald zu lodash konvertieren.kann nicht das gewünschte Ergebnis Array

Daten

var doctors = [ 
    { 
    "id": 0, 
    "dateOfEmployment": "2012-12-27", 
    "dateOfTermination": "2015-01-13", 
    "dateOfBirth": "1978-06-06", 
    "gender": "Male" 
    }, 
    { 
    "id": 1, 
    "dateOfEmployment": "2016-02-08", 
    "dateOfTermination": null, 
    "dateOfBirth": "1984-04-21", 
    "gender": "Female" 
    }, 
    { 
    "id": 2, 
    "dateOfEmployment": "2010-11-30", 
    "dateOfTermination": "2015-09-03", 
    "dateOfBirth": "1975-09-24", 
    "gender": "Male" 
    }, 
    { 
    "id": 3, 
    "dateOfEmployment": "2012-06-17", 
    "dateOfTermination": null, 
    "dateOfBirth": "1980-08-31", 
    "gender": "Female" 
    },..]; 

Ich mag würde ein Ergebnis von Array für die letzten 2 Jahre erhalten:

[{ date: '2015-04', count: 22 }, 
{ date: '2015-05', count: 25 }, 
...] 

Am Anfang dieses habe ich versucht:

doctors = doctors.filter(function(doctor){ 
      return moment(doctor.dateOfEmployment).isBetween('2014-04', '2016-04'); 
      }).map(function(doctor){ 
       return { 
      dates: moment(doctor.dateOfEmployment).format('YYYY-MM'), 
      count: new Date(doctor.dateOfEmployment) - new Date(doctor.dateOfEmployment) + 1 }; 
     });); 


console.log(doctors); 

Ich bin verwirrt. Sollte ich zuerst ein neues Array von Ärzten mit nur ID, dateOfEmployment, dateOfTermination erstellen und beide Daten zu einem Moment machen. Filtern Sie dann das neue Datumsfeld mit einer Bedingung, in der das Moment zwischen den Jahren liegt, und dann mappen/reduzieren.

I von Brute-Force-Methode dachte, wo ich würde Schleife an jedem Arzt über 24mal und einen Zähler unter der Bedingung, basierend erhöhen, wenn doctorsEmployment Datum und doctorsTermination Datum entweder null oder gleich dem vorübergehenden Datum ist .Das temporäre Datum beginnt mit "2014-04" bis "2016-04" und drückt schließlich auf das Ergebnisobjekt.

Bin ich dieses Problem in einer falschen Weise nähern?

Jede Hilfe wird sehr geschätzt!

+2

ich so das Gefühl ist eher ein * reduzieren * Betrieb als ein * Filter/Karte *. – Phil

+0

anstelle der Abbildung, versuchen Sie dies: '_.groupBy (filteredArray, Arzt => vor (doctor.dateOfEmployment) .format ('YYYY-MM'))' – Thomas

+0

Wie Phil sagt, sind Sie ein Array mit * Filter erstellen *, dann gehen Sie darüber und ein anderes Array mit * map * erstellen. Mit * reduce * können Sie beide in einer Iteration tun, um ein Array zu erstellen. Es ist wahrscheinlich auch viel effizienter, die Datumszeichenfolgen in Daten vor dem Aufruf der Funktion zu konvertieren, andernfalls erstellen Sie auch neue Dates oder moment.js-Instanzen in jeder Schleife. – RobG

Antwort

0

wie nur lodash des reduzieren mit ... etwas wie folgt aus:

var doctors = [{ 
    "id": 0, 
    "dateOfEmployment": "2014-12-27", 
    "dateOfTermination": "2015-01-13", 
    "dateOfBirth": "1978-06-06", 
    "gender": "Male" 
}, { 
    "id": 1, 
    "dateOfEmployment": "2016-02-08", 
    "dateOfTermination": null, 
    "dateOfBirth": "1984-04-21", 
    "gender": "Female" 
}, { 
    "id": 2, 
    "dateOfEmployment": "2015-11-30", 
    "dateOfTermination": "2015-09-03", 
    "dateOfBirth": "1975-09-24", 
    "gender": "Male" 
}, { 
    "id": 3, 
    "dateOfEmployment": "2012-06-17", 
    "dateOfTermination": null, 
    "dateOfBirth": "1980-08-31", 
    "gender": "Female" 
}]; 

doctors = _.reduce(doctors, function(memo, doctor) { 
    if (moment(doctor.dateOfEmployment).isBetween('2014-04', '2016-04')) { 
    memo.push({ 
     dates: moment(doctor.dateOfEmployment).format('YYYY-MM'), 
     count: new Date(doctor.dateOfEmployment) - new Date(doctor.dateOfEmployment) + 1 
    }); 
    } 
    return memo; 
}, []); 
console.log(doctors); 

fiddle

+1

Beachten Sie, dass dies nicht eine Zählung der * dateOfEmployment * im selben Monat zusammenfasst, es erstellt ein neues Objekt für jedes so '[{dates:' 2016-02 ', count: 1}, {dates:' 2016-02 ': count: 1}] 'anstatt' [{dates:' 2016-02 ', count: 2}] '. Auch * Daten * nicht * Datum * (geringfügige Fragen ...). ;-) – RobG

1

Nicht lodash oder moment.js arbeiten, aber hier ist, wie es im Klar JS zu tun:

// Sample data 
 
var doctors = [ 
 
    { 
 
    "id": 0, 
 
    "dateOfEmployment": "2012-12-27", 
 
    "dateOfTermination": "2015-01-13", 
 
    "dateOfBirth": "1978-06-06", 
 
    "gender": "Male" 
 
    }, 
 
    { 
 
    "id": 1, 
 
    "dateOfEmployment": "2016-02-08", 
 
    "dateOfTermination": null, 
 
    "dateOfBirth": "1984-04-21", 
 
    "gender": "Female" 
 
    }, 
 
    { 
 
    "id": 2, 
 
    "dateOfEmployment": "2016-02-29", 
 
    "dateOfTermination": "2015-09-03", 
 
    "dateOfBirth": "1975-09-24", 
 
    "gender": "Male" 
 
    }, 
 
    { 
 
    "id": 3, 
 
    "dateOfEmployment": "2015-06-17", 
 
    "dateOfTermination": null, 
 
    "dateOfBirth": "1980-08-31", 
 
    "gender": "Female" 
 
    }]; 
 
    
 
// Parse ISO date string (e.g. 2016-04-01) as local 
 
function parseISODate(s) { 
 
    var b = s.split(/\D/); 
 
    return new Date(b[0], b[1]? b[1] - 1 : 0, b[2] || 1); 
 
} 
 

 
var startDate = parseISODate('2014-04'), 
 
    endDate = parseISODate('2016-04'); 
 

 
// Creates an object with months and counts 
 
var resultObj = doctors.reduce(function(acc, cur) { 
 
    var d = parseISODate(cur.dateOfEmployment); 
 
    if (d >= startDate && d <= endDate) { 
 
    var month = d.toISOString().slice(0,7); 
 
    acc[month] = (acc[month] || 0) + 1; 
 
    } 
 
    return acc; 
 
}, {}); 
 

 
// Creates an array with required objects from result object 
 
var resultArr = Object.keys(resultObj).map(function(key) { 
 
    return {date: key, count: resultObj[key]}; 
 
}) 
 
    
 
document.write(
 
    JSON.stringify(resultObj) + '<br>' + // {"2016-02":2,"2015-06":1} 
 
    JSON.stringify(resultArr) // [{"date":"2016-02","count":2},{"date":"2015-06","count":1}] 
 
);

Dies setzt voraus, dass Sie nur Monate mit einer Zählung größer als Null möchten. Er durchläuft einmal die Originaldaten, dann das Ergebnisobjekt einmal, obwohl ich nicht sehen kann, wie das Array ein wünschenswerteres Format ist als das Objekt, aus dem es erzeugt wurde.

Bitte beachte, dass ich die Quelldaten bearbeitet haben zwei dateOfEmployment Termine im Februar 2016.