我正在使用一个reduce函数,它循环遍历我的JSON文件,并将我指定的键值汇总在一起。
这很好,直到我删除其中一个值。
我的JSON是:
[{
"id": 100,
"jobNumber": 1,
"jobTasks": [{
"id": 12,
"cost": {
"amountString": 100
}
},
{
"id": 13,
"cost": {
"amountString": 500
}
}
]
},
{
"id": 101,
"jobNumber": 2,
"jobTasks": [{
"id": 14,
"cost": {
"amountString": 100
}
},
{
"id": 15
}
]
}
]
我正在使用的reduce函数是:
json.data.forEach(function(item) {
var sum = item.jobTasks.reduce(function(sum, elem) {
return sum + elem.cost.amountString;
}, 0);
console.log('jobNumber' + item.jobNumber + ' ' + sum);
});
我正在努力实现这个目标:
jobNumber1 600
jobNumber2 100
如果我在第二个作业中添加另一个 cost.amountString ,这将正常工作,但是如上面我的JSON中所示,第一个中有两个,第二个中有一个,我收到以下错误:
TypeError: Cannot read property 'amountString' of undefined
reduce 是否需要多个或相同数量的值对才能生效?我尝试了各种for循环但没有成功。
答案 0 :(得分:2)
您需要检查没有属性undefined
的第二个对象的amountString
值。如果对象中不存在属性amountString
,则返回值0
。
因此,请更改return
语句
return sum + elem.cost.amountString;
要强>
return sum + (elem.cost && elem.cost.amountString ? elem.cost.amountString : 0) ;
完整代码:
var json = {};
json.data = [{
"id": 100,
"jobNumber": 1,
"jobTasks": [{
"id": 12,
"cost": {
"amountString": 100
}
},
{
"id": 13,
"cost": {
"amountString": 500
}
}
]
},
{
"id": 101,
"jobNumber": 2,
"jobTasks": [{
"id": 14,
"cost": {
"amountString": 100
}
},
{
"id": 15
}
]
}
]
json.data.forEach(function(item) {
var sum = item.jobTasks.reduce(function(sum, elem) {
return sum + (elem.cost && elem.cost.amountString ? elem.cost.amountString : 0) ;
}, 0);
console.log('jobNumber' + item.jobNumber + ' ' + sum);
});

答案 1 :(得分:1)
TypeError:无法读取未定义
的属性'amountString'
这种情况正在发生,因为您试图取消引用未定义的值。您基本上是在撰写return sum + undefined.amountString
,这与撰写return sum + null.amountString
类似。你怎么解决这个问题?
除了Agalo建议的内容之外,我们还可以过滤有成本的jobTask对象:
json.data.forEach(function(item) {
var sum = item.jobTasks
.filter(function (j) { return j.cost; })
.reduce(function(sum, elem) {
return sum + elem.cost.amountString;
}, 0);
console.log('jobNumber' + item.jobNumber + ' ' + sum);
});
顺便说一句,请考虑使用箭头语法,因为它可以说更具可读性。
json.data.forEach((item) => {
var sum = item.jobTasks
.filter((j) => j.cost)
.reduce((sum, elem) => sum + elem.cost.amountString, 0);
console.log('jobNumber' + item.jobNumber + ' ' + sum);
});
完整的代码清单:
var json = {};
json.data = [{
"id": 100,
"jobNumber": 1,
"jobTasks": [{
"id": 12,
"cost": {
"amountString": 100
}
},
{
"id": 13,
"cost": {
"amountString": 500
}
}
]
},
{
"id": 101,
"jobNumber": 2,
"jobTasks": [{
"id": 14,
"cost": {
"amountString": 100
}
},
{
"id": 15
}
]
}
];
// with traditional functions
json.data.forEach(function(item) {
var sum = item.jobTasks
.filter(function(j) {
return j.cost;
})
.reduce(function(sum, elem) {
return sum + elem.cost.amountString;
}, 0);
console.log('jobNumber' + item.jobNumber + ' ' + sum);
});
// with arrow functions
json.data.forEach((item) => {
var sum = item.jobTasks
.filter((j) => j.cost)
.reduce((sum, elem) => sum + elem.cost.amountString, 0);
console.log('jobNumber' + item.jobNumber + ' ' + sum);
});