如何在JavaScript中遍历JSON数组

9

是的,有很多关于这个的帖子。但我的疑问有点不同。例如,我有以下数组:

var dictionary = {
    "12Jan2013": [{
        "id": "0",
        "name": "ABC"
    }, {
        "id": "1",
        "name": "DEF"
    }],
    "13Jan2013": [{
        "id": "0",
        "name": "PQR"
    }, {
        "id": "1",
        "name": "xyz"
    }]
};

在同一个网站上有相同的帖子,但是在字典中json数组键是动态的。这里是日期,即12Jan2013。它可以是任何日期。它不是静态的。我已经搜索过了,但没有找到解决方案。

如何迭代这样的json数组?

如何按与上述相同的格式打印json数组?

编辑

这是我的真实代码。在下面的代码中i显示了一个注释,其中我想迭代数据,即jsonData变量在getWeatherDataForCities回调中

var arrAllrecords = [];
var arrCityrecordForADay = [];
function getWeatherDataForCities(cityArray, callback){

var toDaysTimestamp = Math.round((new Date()).getTime() / 1000) - (24*60*60);
for(var i in cityArray){

    for(var j=1; j<=1; j++){
        var jsonurl = "http://api.openweathermap.org/data/2.5/history/city?q="+cityArray[i]+"&dt="+toDaysTimestamp;

        $.ajax({
            url: jsonurl,
            dataType: "jsonp",
            mimeType: "textPlain",
            crossDomain: true,
            contentType: "application/json; charset=utf-8",
            success: function(data){                    
                var arrCityRecordForDay = [];
                /*arrCityrecordForADay.push(data.list[0].city.name);
                arrCityrecordForADay.push(data.list[0].weather[0].description);
                arrCityrecordForADay.push(timeConverter(data.list[0].dt));
                arrCityrecordForADay.push(data.list[0].main.temp);
                arrCityrecordForADay.push(data.list[0].main.humidity);
                arrCityrecordForADay.push(data.list[0].main.pressure)
                arrCityrecordForADay.push(data.list[0].wind.speed);*/
                //'{"pets":[{"name":"jack"},{"name":"john"},{"name":"joe"}]}';

                arrCityRecordForDay.push(
                    {"cityName" : data.list[0].city.name},
                    {"weather" : data.list[0].weather[0].description}
                );

                var tempId = data.list[0].city.name+"-"+timeConverter(data.list[0].dt);

                arrCityrecordForADay.push(
                    {tempId : arrCityRecordForDay}
                );

                if(((arrCityrecordForADay.length)) === cityArray.length) {
                    callback(arrCityrecordForADay);
                }

        } });
        toDaysTimestamp = toDaysTimestamp - (24*60*60);
    }   
}       
}

$(document ).ready(function() {

 var cityArray = new Array();
  cityArray[0] = "pune";

  getWeatherDataForCities(cityArray, function(jsonData) {
        // Here I want to iterate jsonData
  });


});

3
那不是JSON数组,那是JS数组对象。它们并不相同。JSON是一种数据序列化格式。 - Benjamin Gruenbaum
Duplicate - Prateek
我不是重复的。这里有像数据这样的常量键,也有动态的。我对于那是JSON还是仅仅是数组感到困惑,就像Benjamin上面所说的一样。 - Prashant Shilimkar
4个回答

10

使用 for-in... 类似于以下方式:

for (var i in dictionary) {
    dictionary[i].forEach(function(elem, index) {
        console.log(elem, index);
    });
}

其中 i 将迭代您的 dictionary 对象,然后您可以使用 forEach 处理字典中每个json数组(使用dictionary[i]

使用此代码,您将获得

Object {id: "0", name: "ABC"} 0 
Object {id: "1", name: "DEF"} 1 
Object {id: "0", name: "PQR"} 0 
Object {id: "1", name: "xyz"} 1 

你可以根据自己的需要定制forEach函数的定义(替换console.log部分),以此来实现你想要的功能。

演示

编辑:使用Object.keys完成同样的操作

Object.keys(dictionary).forEach(function(key) {
    dictionary[key].forEach(function(elem, index) {
        console.log(elem, index);
    });
});

编辑2: 鉴于您的jsonData对象结构比较复杂,您可以尝试使用一种(有点)通用的函数,分别对每种类型的组件进行操作。我可能错过了一些情况,但也许可以尝试:

function strung(arg) {
    var ret = '';
    if (arg instanceof Array) {
        arg.forEach(function(elem, index) {
            ret += strung(elem) + ',';
        });
    } else if (arg instanceof Object) {
        Object.keys(arg).forEach(function(key) {
            ret += key + ': /' + strung(arg[key]) + '/';
        });
    } else if (typeof arg === "string" || typeof arg === "number") {
        ret = arg;
    }
    return ret;
}

document.body.innerHTML = strung(jsonData);

演示


1
如果你正在使用 forEach,那么最好使用 Object.keys,让你的代码更加漂亮 :) - Benjamin Gruenbaum
还要注意,您还需要使用hasOwnProperty(i)来过滤可能已被继承的属性。 - Ryan Ransford
1
@BenjaminGruenbaum 我对 Object.keys 不太熟悉,不如我想象的那么熟练...我已经在我的回答中添加了一个编辑。那是你想要的吗? - tewathia
1
@PrashantShilimkar 我已经在我的回答中添加了fiddle链接。请看一下。 - tewathia
1
@PrashantShilimkar 一眼看去,你的代码对我来说看起来还不错(我假设 timeConverter 在其他地方已经定义)。但是请注意,你不能直接使用我的答案与你的 jsonData 对象,因为它们的结构略有不同。请参考这个 fiddle - tewathia
显示剩余5条评论

1
请注意,你的对象只是一个 JavaScript 数组对象。为了更容易理解,你可以像这样迭代它:
for (var i in dictionary) {
    // do something with i
    // here i will contain the dates

    for (n = 0; n < dictionary[i].length; n++) {
        // do something with the inner array of your objects    
        // dictionary[i][n].id contains the "id" of nth object in the object i
        // dictionary[i][n].name contains the "name" of nth object in the object i
    }
}

请查看这个代码片段:http://jsfiddle.net/Ke8F5/

迭代过程如下:

12Jan2013 : (id = 0, name = ABC) (id = 1, name = DEF)  
13Jan2013 : (id = 0, name = PQR) (id = 1, name = XYZ)

谢谢。我已经编辑了我的问题,其中我创建了一个动态的JSON数组。这是正确的方式吗?还是我所做的是正确的? - Prashant Shilimkar
@PrashantShilimkar:这完全取决于您的ajax调用中data的结构。尽管如此,概念仍然是相同的。 - Abhitalks

0
你可以使用 for 循环。
for (var i in json) {
 ...
}

那么,i是当前的键,因此,您可以访问json [i]并获取相应索引的数据。

然后,如果您需要迭代内部元素,可以执行相同的操作。


0

你可以使用 for ... in,但是你应该结合 hasOwnProperty 使用,否则你会发现自己正在迭代继承的属性,很可能会破坏你的代码。

  for (var key in object) {
    if (object.hasOwnProperty(key)) {
        // Do stuff.
    }
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接