2011-09-15 5 views
1

文字列をキーとして使用する別の配列の内部にネストされたURLのインデックス付き配列があります。両方の配列から情報を抽出する必要があり、次のループを使用しています。連想配列(JS)内でインデックス付き配列を循環するループをネストする方法

// 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呼び出しを実行します。しかし、最初の配列の最初の要素で終了すると、2番目の配列に進まず、ITの内部配列データを取得します。

説明があまりにもうんざりしていないことを願っています。

あなたはより明確にするため、ここで完全なコードを見ることができます:あなたのデータ構造を仮定しhttp://jsfiddle.net/FvP5f/

答えて

2

は、プロパティの配列を持つオブジェクトである、あなたはこのようにそれを行うだろう。

  1. serviceCategoriesは配列ではなく、オブジェクトでなければなりません。 Javascriptには連想配列はありません。これは、キーによる格納およびキーによる反復のためのオブジェクトを有する。配列インデックスは数値です。
  2. 各埋め込み配列の長さにわたって実際に反復処理する必要があります。
  3. 成功ハンドラ内の変数keyを参照することはできません。これは、値が変更されるようにループの後に呼び出されるためです。この問題を解決するために、成功ハンドラの「this」ポインタとして設定されるコンテキストオブジェクトにキーを配置し、キーに戻ることができます。

は、ここでそれらの問題を解決するためのコードです:

// 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); 
       } 
      } 
     });  
    } 
} 
+0

これはうまくいきました。一つの問題が残っている。結果は各ページの更新時にランダムな順序で書き込まれます。つまり、配列内のURLの順序は確認されません。それはこのコードによって引き起こされる可能性がありますか、または結果を解析するコード(これはhttp://jsfiddle.net/cNY5x/で見つかる可能性が高いです)。苦しんでいるルーキーのおかげで... – Fernando

+0

ajaxの結果は非同期的に受信され、特定の順序で戻ってこないかもしれません。何らかの順序でそれらがすべて必要な場合は、結果を一連の結果に蓄積し、すべて受信したときに並べ替えてから、必要な順序で処理する必要があります。 – jfriend00

+0

もう一度大変感謝します!また、私が使用しているjquery ajaxメソッドでasyncオプションをfalseに設定できることを実現しました... – Fernando

1

まあ、一つの問題は、あなたの配列の第2次元は、同じサイズ(すなわちkeyCnt)が常にあると仮定していることのようです。あなたはまた、間違った方向を数えているように見えます。つまり、2つのinGoodHandsとspaRitualsを取得し、2番目のインデックスはinGoodHandsの2つで、3つはspaRitualsです)。

あなたはこのような何かをやるべきように思える:

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

Javascriptの範囲は機能ではなく、ブロックです。 var curcatをforループの内側に置くことができますが、繰り返しごとに異なる変数を作成していないことを理解することが重要です。

これは、ループで作成しているすべてのクロージャが実際に同じ変数に基づいていることを意味しているので、おそらく最初の作品だけではなく、最後のキー。

javascriptでローカルスコープを作成するソリューションは、ローカル関数を使用することです。代わりに

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

のあなたは名前xは区別を明確にするcurcatの代わりに使用されてきた

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

を使用することができます。

この変数は、実際に作成されたクロージャごとに別々になります。

関連する問題