如何用更合适的 lodash 函数替换嵌套的 foreach 循环?
How can I replace nested foreach loops with more appropriate lodash functions?
我想完善我的函数式编程知识,更具体地说是 lodash 的数据处理函数。我在下面整理了一个合理的示例,我非常希望看到它以不同的方式完成,最好没有显式的 forEach 循环。
给定以下数据集:
// dateArray JSON
["2015-06-01T04:00:00.000Z", "2015-06-02T04:00:00.000Z", "2015-06-03T04:00:00.000Z"]
// projectList JSON
[{
"_id": "53d487607464e4954927ba1c",
"name": "Development"
}, {
"_id": "540e104f7464e48d2f524560",
"name": "My Aw&some Proj&ct"
}, {
"_id": "52168d64839f153950000218",
"name": "Internal Marketing"
}, {
"_id": "5464e5787464e42e6df38da8",
"name": "Communication"
}, {
"_id": "NA",
"name": "Not Assigned"
}]
// activeProjectList JSON
[{
"date": "2015-6-1",
"projects": [{
"_id": "53d487607464e4954927ba1c",
"h": 1
}, {
"_id": "NA",
"h": 2.5
}]
}, {
"date": "2015-6-2",
"projects": [{
"_id": "540e104f7464e48d2f524560",
"h": 1
}, {
"_id": "NA",
"h": 2
}]
}, {
"date": "2015-6-3",
"projects": [{
"_id": "52168d64839f153950000218",
"h": 1
}, {
"_id": "5464e5787464e42e6df38da8",
"h": 3.25
}, {
"_id": "NA",
"h": 0.5
}]
}];
您将如何在避免 foreach 循环并支持更合适的 lodash 函数的同时将其压缩成下面的结果?
// series JSON (result)
[{
"name": "Development",
"data": [1, 0, 0]
}, {
"name": "Not Assigned",
"data": [2.5, 2, 0.5]
}, {
"name": "My Aw&some Proj&ct",
"data": [0, 1, 0]
}, {
"name": "Internal Marketing",
"data": [0, 0, 1]
}, {
"name": "Communication",
"data": [0, 0, 3.25]
}]
这是我目前最好的尝试:
_.map(activeProjectList, function (item) {
item.date = new Date(item.date).toISOString();
return item;
});
projectList = _.indexBy(projectList, '_id');
var projectTimes = {};
_.forEach(activeProjectList, function (item) {
_.forEach(item.projects, function (subItem) {
if (!projectTimes[subItem._id]) projectTimes[subItem._id] = {};
projectTimes[subItem._id][item.date] = subItem.h;
});
});
var series = [];
var seriesData;
_.forEach(projectTimes, function (item, key) {
seriesData = [];
_.forEach(dateArray, function (date) {
if (item[date]) seriesData.push(item[date]);
else seriesData.push(0);
});
series.push({
name: projectList[key].name,
data: seriesData
});
});
这里有一个 fiddle 上面的实现:http://jsfiddle.net/8fe5oo49/
感谢您的宝贵时间。
不确定最终输出的顺序有多重要。对我来说,按最初定义的顺序排列项目列表 return 更有意义,但这可能不是您想要的
var series = _.map(projectList, function(project){
return {
'name': project.name,
'data': _.map(dateArray, function(date){
var p = _.findWhere(
_.find(activeProjectList, function(activeProj){
return new Date(activeProj.date).toISOString() == date
}).projects,
{_id: project._id}
)
return (p ? p.h : 0)
})
}
});
这将return
[
{"name":"Development","data":[1,0,0]},
{"name":"My Aw&some Proj&ct","data":[0,1,0]},
{"name":"Internal Marketing","data":[0,0,1]},
{"name":"Communication","data":[0,0,3.25]},
{"name":"Not Assigned","data":[2.5,2,0.5]}
]
我想完善我的函数式编程知识,更具体地说是 lodash 的数据处理函数。我在下面整理了一个合理的示例,我非常希望看到它以不同的方式完成,最好没有显式的 forEach 循环。
给定以下数据集:
// dateArray JSON
["2015-06-01T04:00:00.000Z", "2015-06-02T04:00:00.000Z", "2015-06-03T04:00:00.000Z"]
// projectList JSON
[{
"_id": "53d487607464e4954927ba1c",
"name": "Development"
}, {
"_id": "540e104f7464e48d2f524560",
"name": "My Aw&some Proj&ct"
}, {
"_id": "52168d64839f153950000218",
"name": "Internal Marketing"
}, {
"_id": "5464e5787464e42e6df38da8",
"name": "Communication"
}, {
"_id": "NA",
"name": "Not Assigned"
}]
// activeProjectList JSON
[{
"date": "2015-6-1",
"projects": [{
"_id": "53d487607464e4954927ba1c",
"h": 1
}, {
"_id": "NA",
"h": 2.5
}]
}, {
"date": "2015-6-2",
"projects": [{
"_id": "540e104f7464e48d2f524560",
"h": 1
}, {
"_id": "NA",
"h": 2
}]
}, {
"date": "2015-6-3",
"projects": [{
"_id": "52168d64839f153950000218",
"h": 1
}, {
"_id": "5464e5787464e42e6df38da8",
"h": 3.25
}, {
"_id": "NA",
"h": 0.5
}]
}];
您将如何在避免 foreach 循环并支持更合适的 lodash 函数的同时将其压缩成下面的结果?
// series JSON (result)
[{
"name": "Development",
"data": [1, 0, 0]
}, {
"name": "Not Assigned",
"data": [2.5, 2, 0.5]
}, {
"name": "My Aw&some Proj&ct",
"data": [0, 1, 0]
}, {
"name": "Internal Marketing",
"data": [0, 0, 1]
}, {
"name": "Communication",
"data": [0, 0, 3.25]
}]
这是我目前最好的尝试:
_.map(activeProjectList, function (item) {
item.date = new Date(item.date).toISOString();
return item;
});
projectList = _.indexBy(projectList, '_id');
var projectTimes = {};
_.forEach(activeProjectList, function (item) {
_.forEach(item.projects, function (subItem) {
if (!projectTimes[subItem._id]) projectTimes[subItem._id] = {};
projectTimes[subItem._id][item.date] = subItem.h;
});
});
var series = [];
var seriesData;
_.forEach(projectTimes, function (item, key) {
seriesData = [];
_.forEach(dateArray, function (date) {
if (item[date]) seriesData.push(item[date]);
else seriesData.push(0);
});
series.push({
name: projectList[key].name,
data: seriesData
});
});
这里有一个 fiddle 上面的实现:http://jsfiddle.net/8fe5oo49/
感谢您的宝贵时间。
不确定最终输出的顺序有多重要。对我来说,按最初定义的顺序排列项目列表 return 更有意义,但这可能不是您想要的
var series = _.map(projectList, function(project){
return {
'name': project.name,
'data': _.map(dateArray, function(date){
var p = _.findWhere(
_.find(activeProjectList, function(activeProj){
return new Date(activeProj.date).toISOString() == date
}).projects,
{_id: project._id}
)
return (p ? p.h : 0)
})
}
});
这将return
[
{"name":"Development","data":[1,0,0]},
{"name":"My Aw&some Proj&ct","data":[0,1,0]},
{"name":"Internal Marketing","data":[0,0,1]},
{"name":"Communication","data":[0,0,3.25]},
{"name":"Not Assigned","data":[2.5,2,0.5]}
]