我正在学习lodash和moment.js,我正在使用一些虚拟数据。虚拟数据包含1000名医生的名单。我已经开始使用 Array.prototype.map()和 Array.prototype.filter(),很快就会将它们转换为lodash。
数据
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"
},..];
我想获得过去两年的数组结果:
[{ date: '2015-04', count: 22 },
{ date: '2015-05', count: 25 },
...]
最初我试过这个:
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);
我很困惑。我是否应该首先创建一个新的医生阵列,其中只有 id , dateOfEmployment , dateOfTermination 并将这两个日期分开。然后用一个条件过滤新的日期数组,其中矩为年,然后是map / reduce。
我确实想到了蛮力方法,我会对每位医生进行24次循环,并根据医生就业日期和 doctorsTermination 日期的条件增加一个计数器为null或等于临时日期。临时日期从“2014-04”开始到“2016-04”,最后将其推送到数组结果对象。
我是否以错误的方式解决了这个问题?
任何帮助将不胜感激!
答案 0 :(得分:1)
不是lodash或moment.js,但是这里是如何在普通的JS中做到的:
// 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}]
);
&#13;
这假设您只需要计数大于零的月份。它遍历原始数据一次,然后是结果对象一次,但我不能看到数组是如何比它创建的对象更理想的格式。
请注意,我在2016年2月编辑了源数据,以便有两个 dateOfEmployment 日期。
答案 1 :(得分:0)
如何使用lodash减少...这样的事情:
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