Javascript Lodash代码优化/重构
这是原始JSON数据:Javascript Lodash代码优化/重构,javascript,json,lodash,Javascript,Json,Lodash,这是原始JSON数据: var data= [ { project: "ABC", area: 'Test', subArea: 'Dev', done: 10 }, { project: "ABC", area: 'Test', subArea: 'QA', done: 10 }, { project: "ABC", area: 'Test', subArea: 'Support', d
var data= [
{ project: "ABC", area: 'Test', subArea: 'Dev', done: 10 },
{ project: "ABC", area: 'Test', subArea: 'QA', done: 10 },
{ project: "ABC", area: 'Test', subArea: 'Support', done: 10 },
{ project: "ABC", area: 'External', subArea: 'Dev', done: 5 },
{ project: "ABC", area: 'External', subArea: 'QA', done: 5 },
{ project: "ABC", area: 'External', subArea: 'Support', done: 5 },
{ project: "ABC", area: 'Escalation', subArea: 'Dev', done: 20 },
{ project: "ABC", area: 'Escalation', subArea: 'QA', done: 20 },
{ project: "ABC", area: 'Escalation', subArea: 'Support', done: 20 },
{ project: "ABC123", area: 'Test', subArea: 'Dev', done: 20 },
{ project: "ABC123", area: 'Test', subArea: 'QA', done: 20 },
{ project: "ABC123", area: 'Test', subArea: 'Support', done: 20 },
{ project: "ABC123", area: 'External', subArea: 'Dev', done: 10 },
{ project: "ABC123", area: 'External', subArea: 'QA', done: 10 },
{ project: "ABC123", area: 'External', subArea: 'Support', done: 10 },
{ project: "ABC123", area: 'Escalation', subArea: 'Dev', done: 5 },
{ project: "ABC123", area: 'Escalation', subArea: 'QA', done: 5 },
{ project: "ABC123", area: 'Escalation', subArea: 'Support', done: 5 },
];
我需要的是按项目对项目进行分组,将它们划分为区域,并对每个子区域的完成时间进行汇总。新的JSON结果必须如下所示:
[
{
"name": "ABC",
"test": {
"total": 30,
"totalDev": 10,
"totalQA": 10,
"totalSup": 10
},
"external": {
"total": 15,
"totalDev": 5,
"totalQA": 5,
"totalSup": 5
},
"escalation": {
"total": 60,
"totalDev": 20,
"totalQA": 20,
"totalSup": 20
}
},
{
"name": "ABC123",
"test": {
"total": 60,
"totalDev": 20,
"totalQA": 20,
"totalSup": 20
},
"external": {
"total": 30,
"totalDev": 10,
"totalQA": 10,
"totalSup": 10
},
"escalation": {
"total": 15,
"totalDev": 5,
"totalQA": 5,
"totalSup": 5
}
}
]
_.reduce(_.filter(projectGroup, ...), sum, 0)
下面是我的实际代码,我已经得到了我想要的结果,但我认为代码可以更优化。无需重复和所有条件验证,无需硬编码映射块内的区域和子区域属性,因为这些值在服务器端是动态区域
var sum = (total, item) => total += item.done;
result = _.chain(data)
.groupBy(function(value) { return value.project })
.map((projectGroup, projectName) => ({
name: projectName,
test: {
total: _.reduce(_.filter(projectGroup, (o) => ( o.area === 'Test')) , sum, 0),
totalDev: _.reduce(_.filter(projectGroup, (o) => ( o.area === 'Test' && o.subArea === 'Dev')) , sum, 0),
totalQA: _.reduce(_.filter(projectGroup, (o) => ( o.area === 'Test' && o.subArea === 'QA')) , sum, 0),
totalSup: _.reduce(_.filter(projectGroup, (o) => ( o.area === 'Test' && o.subArea === 'Support')) , sum, 0)
},
external: {
total: _.reduce(_.filter(projectGroup, (o) => ( o.area === 'External')) , sum, 0),
totalDev: _.reduce(_.filter(projectGroup, (o) => ( o.area === 'External' && o.subArea === 'Dev')) , sum, 0),
totalQA: _.reduce(_.filter(projectGroup, (o) => ( o.area === 'External' && o.subArea === 'QA')) , sum, 0),
totalSup: _.reduce(_.filter(projectGroup, (o) => ( o.area === 'External' && o.subArea === 'Support')) , sum, 0)
},
escalation: {
total: _.reduce(_.filter(projectGroup, (o) => ( o.area === 'Escalation')) , sum, 0),
totalDev: _.reduce(_.filter(projectGroup, (o) => ( o.area === 'Escalation' && o.subArea === 'Dev')) , sum, 0),
totalQA: _.reduce(_.filter(projectGroup, (o) => ( o.area === 'Escalation' && o.subArea === 'QA')) , sum, 0),
totalSup: _.reduce(_.filter(projectGroup, (o) => ( o.area === 'Escalation' && o.subArea === 'Support')) , sum, 0)
}
}))
我不知道你想在这里优化什么,lodash应该代替你来做。我只有一句话
var sum = (total, item) => total += item.done;
function reduceData(projectGroup, projectName, comparationLabel) {
return {
total: _.reduce(_.filter(projectGroup, (o) => ( o.area === comparationLabel)) , sum, 0),
totalDev: _.reduce(_.filter(projectGroup, (o) => ( o.area === comparationLabel && o.subArea === 'Dev')) , sum, 0),
totalQA: _.reduce(_.filter(projectGroup, (o) => ( o.area === comparationLabel && o.subArea === 'QA')) , sum, 0),
totalSup: _.reduce(_.filter(projectGroup, (o) => ( o.area === comparationLabel && o.subArea === 'Support')) , sum, 0)
}
}
result = _.chain(data)
.groupBy(function(value) { return value.project })
.map((projectGroup, projectName) => ({
name: projectName,
test: reduceData(projectGroup, projectName, 'Test'),
external: reduceData(projectGroup, projectName, 'External'),
escalation: reduceData(projectGroup, projectName, 'Escalation')
}))
是的,如果要进行某种缓存,可以避免使用
.filter(projectGroup,(o)
,但这样可以节省少量的程序资源。而不是像这样嵌套:
[
{
"name": "ABC",
"test": {
"total": 30,
"totalDev": 10,
"totalQA": 10,
"totalSup": 10
},
"external": {
"total": 15,
"totalDev": 5,
"totalQA": 5,
"totalSup": 5
},
"escalation": {
"total": 60,
"totalDev": 20,
"totalQA": 20,
"totalSup": 20
}
},
{
"name": "ABC123",
"test": {
"total": 60,
"totalDev": 20,
"totalQA": 20,
"totalSup": 20
},
"external": {
"total": 30,
"totalDev": 10,
"totalQA": 10,
"totalSup": 10
},
"escalation": {
"total": 15,
"totalDev": 5,
"totalQA": 5,
"totalSup": 5
}
}
]
_.reduce(_.filter(projectGroup, ...), sum, 0)
可以这样做以防止在集合上循环两次:
_(projectGroup).filter(...).reduce(sum, 0).value()
为什么不在普通Javascript中使用单个循环来分组和汇总小时数 此提案使用哈希表,并按
project
属性的值进行分组
var data=[{project:'ABC',area:'Test',subArea:'Dev',done:10},{project:'ABC',area:'Test',subArea:'Support',done:10},{project:'ABC',area:'Dev',done:5},{project:'ABC',area ternal QA',done:5},{project:'ABC',区域:'外部',分区:'支持',完成:5},{project:'ABC',区域:'升级',分区:'开发',完成:20},{project:'ABC',区域:'升级',分区:'QA',完成:20},{project:'ABC',区域:'升级',分区:'支持',完成:20},{project:'ABC123',区域:'测试',分区:'开发',完成:20},{project:'ABC123',区域:'Test',分区:'QA',完成时间:20},{project:'ABC123',区域:'Support',完成时间:20},{project:'ABC123',区域:'External',分区:'Dev',完成时间:10},{project:'ABC123',分区:'Support',完成时间:10},{project:'ABC123',分区:'Support,区域:'Escalation',子区域:'Dev',done:5},{project:'ABC123',区域:'Escalation',子区域:'QA',done:5},{project:'ABC123',区域:'Escalation',子区域:'Support',done:5},
结果=[];
data.forEach(函数(a){
var area=a.area.toLowerCase(),
分区=‘总计’+a.分区;
如果(!此[a.项目]){
此[a.project]={name:a.project};
结果推送(这个[一个项目]);
}
此[a.project][area]=此[a.project][area]|{总计:0};
此[a.项目][区域][分区]=(此[a.项目][区域][分区]| | 0)+a.完成;
此[a.项目][区域].total+=a.完成;
},Object.create(null));
console.log(结果);
.as控制台包装{max height:100%!important;top:0;}
.groupBy(函数(值){return value.project})
可以是.groupBy('project'))
为什么abc test totaldev=30?数字来自哪里?我编辑了,现在它是正确的。谢谢!这就是我要找的!谢谢!你的代码非常好,解决了我的问题,但我现在觉得使用Lodash更舒服。谢谢!我会做出更改。