我正在学习如何从JSON文件中检索数据并充分利用它,我发现for..in循环很有用,但我知道我做的太多了,无法获得一个值一个JSON文件。
这是我的JSON - 它不必以这种方式构建。
var dollars = { "zipcodes": {
"one": {
"donors": {
"donor_profile1": {
"name": "Doug Smith",
"address" : "123 main st",
"gifts":{
"gift0": {
"recipient":"Greg",
"amount": 45000,
"date":"7/1/2013"
},
"gift1":{
"recipient":"Greg",
"amount": 6000,
"date":"7/1/2013"
},
"gift2":{
"recipient":"Marty",
"amount": 2000,
"date":"7/1/2013"
}
}
},
"donor_profile2": {
"name": "Bert Bernard",
"address" : "123 South st",
"gifts": {
"gift0": {
"recipient":"Greg",
"amount": 1200,
"date":"7/4/2013"
},
"gift1":{
"recipient":"Marty",
"amount": 400,
"date":"7/9/2013"
},
"gift2":{
"recipient":"Marty",
"amount": 510,
"date":"7/21/2013"
}
}
}
}
}
我想收集每位捐赠者提供的所有礼物并将其加起来。我已经写了这个程序来获得所有的礼物金额,但它们没有被捐赠者分开。关于如何制作这种清洁剂的任何建议?
var info = dollars.zipcodes.one;
function buildSum(){
for (var key in info){
if (info.hasOwnProperty(key)) {
var person = info[key];
};
for (prop in person) {
if(person.hasOwnProperty(prop)){
var name = person[prop].gifts;
};
for(value in name){
if(name.hasOwnProperty(value)){
var money = name[value].amount;
};
}
}
}
}
buildSum();
答案 0 :(得分:2)
如评论部分所述,您可能应该使用适合的数组。所以你的JSON数据可能如下所示:
var dollars = {
"zipcodes": {
"one": {
"donors": [{
"name": "Doug Smith",
"address": "123 main st",
"gifts": [{
"recipient": "Greg",
"amount": 45000,
"date": "7/1/2013"
}, {
"recipient": "Greg",
"amount": 6000,
"date": "7/1/2013"
}, {
"recipient": "Marty",
"amount": 2000,
"date": "7/1/2013"
}]
}, {
"name": "Bert Bernard",
"address": "123 South st",
"gifts": [{
"recipient": "Greg",
"amount": 1200,
"date": "7/4/2013"
}, {
"recipient": "Marty",
"amount": 400,
"date": "7/9/2013"
}, {
"recipient": "Marty",
"amount": 510,
"date": "7/21/2013"
}]
}]
}
}
};
这使您可以使用Array.prototype
的某些功能。在我的情况下,我使用Array.map和Array.reduce来生成一个数组,其中包含每个捐赠者捐赠的总金额:
//first map: turn the array of donors in an array of gift array
var res = dollars.zipcodes.one.donors.map(function (item) {
//second map: turn each gift array in an array of amount
return item.gifts.map(function (item) {
return item.amount;
//use reduce to sum up the amount in each array
}).reduce(function (a, b) {
return a + b;
});
});
console.log(res); //[53000, 2110]
<强> FIDDLE 强>
答案 1 :(得分:1)
if (info.hasOwnProperty(key))
您不需要检查。您的值是普通对象,没有人足够愚蠢地使用可枚举属性扩展Object.prototype
。
for (prop in person)
这似乎是不必要的,如果没有错的话。您只想访问gifts
属性,因此无需枚举name
,address
和gifts
。与
for (var key in info)
你只想获得donors
并迭代它们 - 该对象甚至没有任何其他属性。
我的JSON不必以这种方式构建
然后我建议为gifts
和donors
集合使用数组,除非那些gift0
,gift1
等是项目的必要ID。
var dollars = {
"zipcodes": {
"one": {
"donors": [
{
"name": "Doug Smith",
"address": "123 main st",
"gifts": [
{
"recipient": "Greg",
"amount": 45000,
"date": "7/1/2013"
},
{
"recipient": "Greg",
"amount": 6000,
"date": "7/1/2013"
},
{
"recipient": "Marty",
"amount": 2000,
"date": "7/1/2013"
}
]
},
{
"name": "Bert Bernard",
"address": "123 South st",
"gifts": [
{
"recipient": "Greg",
"amount": 1200,
"date": "7/4/2013"
},
{
"recipient": "Marty",
"amount": 400,
"date": "7/9/2013"
},
{
"recipient": "Marty",
"amount": 510,
"date": "7/21/2013"
}
]
}
]
}
}
}
var donors = dollars.zipcodes.one.donors;
sum = 0;
for (var i=0; i<donors.length; i++) {
var donor = donors[i],
gifts = donor.gifts;
var money = 0;
for (var j=0; j<gifts.length; j++) {
money += gifts[j].amount;
}
console.log(donor.name+" spent "+money);
sum += money;
}
console.log("alltogether they spent "+sum);
关于如何制作这种清洁剂的任何建议?
您可以使用Array::reduce
来实现更具功能性的方法:
var sum = dollars.zipcodes.one.donors.reduce(function(s, donor) {
var money = donor.gifts.reduce(function(m, gift) {
return m+gift.amount;
}, 0);
console.log(donor.name+" spent "+money);
return s+money;
}, 0);