如何嵌套循环以循环通过关联数组(JS)内的索引数组

时间:2011-09-15 04:49:46

标签: javascript

我有一个嵌套在另一个数组中的url索引数组,它使用字符串作为键。我需要从两个数组中提取信息,我正在使用以下循环。

    // Loop through the elements in the associative level to get a count of its items   
    var keyCnt = 0;
    for(key in serviceCategories) {
        keyCnt++;
    }
    // Then loop through it again, this time nesting another for loop to get at the inner/indexed arrays
    for(key in serviceCategories) {
        var currCat = key;
            for (var i = 0; i < keyCnt; i++) {
                $.ajax({
                    url: serviceCategories[currCat][i],
                    success: function(data) {
                        parsePageCont (data, currCat);
                    }
                });    
            }
        }
    }

此代码适用于第一个数组的第一个元素。它循环遍历其内部数组,并且对每个url的ajax调用都没有问题。但是,当它完成第一个数组的第一个元素时,它不会进入第二个元素并获取IT内部数组数据。

我希望这个解释不是太混乱了。

您可以在此处查看完整代码,以便更清晰:http://jsfiddle.net/FvP5f/

3 个答案:

答案 0 :(得分:2)

假设您的数据结构是一个包含属性数组的对象,您可以这样做。

  1. serviceCategories必须是一个对象,而不是一个数组。 Javascript没有关联数组。它有按键存储的对象和按键的迭代。数组索引是数字。
  2. 您必须实际迭代每个嵌入式数组的长度。
  3. 您不能在成功处理程序中引用key变量,因为在循环之后很久就会调用它,因此它的值已经更改。为了解决这个问题,我们将密钥放在一个上下文对象中,该对象将被设置为成功处理程序的“this”指针,以便我们可以返回密钥。
  4. 以下是解决这些问题的代码:

    // assume data is of this structure (where I've shown numbers here, they are actually URLs)
    serviceCategories = {
       houses: [1,2,3,4],
       cottages: [5,6,7,8],
       hotels: [8,9,0,1],
       apartments: [2,2,3,4,5,7,8,9]
    };
    
    for (key in serviceCategories) {
        if (serviceCategories.hasOwnProperty(key)) {
            var array = serviceCategories[key];
            // got the next array, iterate through it
            for (var i = 0; i < array.length; i++) {
                var context = {};
                $.ajax({
                    url: array[i],
                    context: {key: key},   // can't refer to key in success handler, so we sest it as context
                    success: function(data) {
                        parsePageCont(data, this.key);
                    }
                }
            });    
        }
    }
    

答案 1 :(得分:1)

好吧,一个问题似乎是你假设你的数组的第二个维度总是相同的大小(即keyCnt)。你似乎也在计算错误的方向,我的意思是你会得到两个(inGoodHands和spaRituals),而你将它用于第二个索引,其中inGoodHands为2,spaRituals为3)。

看起来你应该做这样的事情:

for(x in serviceCategories) {
    for(y in serviceCategories[x]) {
       call ajax for serviceCategories[x][y]
    }
 }

答案 2 :(得分:1)

Javascript范围是函数,而不是块。虽然您可以将var curcat放在for循环中,但重要的是要了解您没有为每次迭代创建不同的变量。

这意味着你在循环中创建的所有闭包实际上都是基于相同的变量,所以你可能观察到的并不是只有第一个有效,而是所有闭包工作都是在最后工作键。

在javascript中创建本地范围的解决方案是使用本地函数;而不是

(function(data){ parsePageCount(data, curcat); })

你可以使用

(function(x){return function(data){ parsePageCount(data, x); };})(curcat)

其中使用了名称x而不是curcat来明确区别。

对于每个创建的闭包,这个变量确实是独立的。