使用 reduce 遍历 JSON
Using reduce to loop through JSON
我正在使用一个 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,这将正常工作,但是如我的 [= 中所示,第一个和第二个中有两个34=] 以上,我得到以下错误:
TypeError: Cannot read property 'amountString' of undefined
reduce 是否需要多个或相同数量的值对才能工作?我试过各种for循环都没有成功。
您需要检查没有 属性 amountString
的第二个对象的 undefined
值。如果 属性 amountString
不存在于对象中,则 return 值 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);
});
TypeError: Cannot read property 'amountString' of undefined
发生这种情况是因为您正试图取消引用未定义的值。您实际上是在写 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);
});
我正在使用一个 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,这将正常工作,但是如我的 [= 中所示,第一个和第二个中有两个34=] 以上,我得到以下错误:
TypeError: Cannot read property 'amountString' of undefined
reduce 是否需要多个或相同数量的值对才能工作?我试过各种for循环都没有成功。
您需要检查没有 属性 amountString
的第二个对象的 undefined
值。如果 属性 amountString
不存在于对象中,则 return 值 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);
});
TypeError: Cannot read property 'amountString' of undefined
发生这种情况是因为您正试图取消引用未定义的值。您实际上是在写 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);
});