3

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

2 回答 2

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]

小提琴

于 2013-07-31T18:49:26.927 回答
1
if (info.hasOwnProperty(key))

你不需要那张支票。您的值是普通对象,没有人愚蠢到可以Object.prototype使用可枚举属性进行扩展。

for (prop in person)

这似乎是不必要的,如果不是错的话。您只想访问该gifts属性,因此无需枚举name,addressgifts。同样的事情

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);
于 2013-07-31T18:50:19.943 回答