使用for..in循环访问JSON数据

时间:2013-07-31 18:05:14

标签: javascript performance

我正在学习如何从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();

2 个答案:

答案 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.mapArray.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属性,因此无需枚举nameaddressgifts。与

相同
for (var key in info)

你只想获得donors并迭代它们 - 该对象甚至没有任何其他属性。

  

我的JSON不必以这种方式构建

然后我建议为giftsdonors集合使用数组,除非那些gift0gift1等是项目的必要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);