2013-05-12 14 views
13

ho una struttura come questa:iterate attraverso una mappa in javascript

var myMap = { 
    partnr1: ['modelA', 'modelB', 'modelC'], 
    partnr2: ['modelA', 'modelB', 'modelC'] 
}; 

vado a scorrere ciascuno degli elementi (partnr) con i loro associatives (modelli).

Sto cercando un doppio $ ciascuna iterazione al fine di raggiungere questo obiettivo, ma non succede nulla:

$.each(myMap, function (i, val) { 
    $.each(i, function (innerKey, innerValue) { 

     setTimeout(function() { 
      $('#variant').fadeOut("slow", function() { 
       $(this).text(innerKey + "-" + innerValue).fadeIn("slow"); 

      }); 

     }, i * 6000); 

    }); 
}); 

L'effetto di dissolvenza dentro e fuori che sto cercando di realizzare è lavorare bene quando si utilizza un unico valore array (Object), ma non quando ho bisogno di avere più di un valore per ogni chiave come qui.

Qualche idea su come eseguire questa iterazione con successo e ci sono altri modi oltre all'utilizzo di una mappa che sarebbe meglio in questo caso?

Eventuali suggerimenti sarebbero di interesse.

+0

Questo non è un 'Mappa', ma un' Oggetto'. –

risposta

3

La richiamata a $.each() passa il nome della proprietà e il valore, in questo ordine. Stai quindi tentando di ripetere i nomi delle proprietà nella chiamata interna a $.each(). Penso che si desidera:

$.each(myMap, function (i, val) { 
    $.each(val, function(innerKey, innerValue) { 
    // ... 
    }); 
}); 

Nel ciclo interno, dato un oggetto come la mappa, i valori sono gli array. Va bene, ma nota che i valori "innerKey" saranno tutti numeri.

modificare — Ora, una volta che è raddrizzato, ecco il problema successivo:

setTimeout(function() { 

     // ... 

    }, i * 6000); 

La prima volta attraverso quel ciclo, "i" sarà la "partnr1" stringa. Pertanto, il tentativo di moltiplicazione risulterà in un NaN. È possibile mantenere un contatore esterno per tenere traccia del conteggio di proprietà della mappa esterna:

var pcount = 1; 
$.each(myMap, function(i, val) { 
    $.each(val, function(innerKey, innerValue) { 
    setTimeout(function() { 
     // ... 
    }, pcount++ * 6000); 
    }); 
}); 
+0

Grazie per la risposta. Cambiando $ .each (i ... in $ .each (val .. il mio codice sopra sta funzionando nel modo in cui mostra un risultato, ma sfortunatamente mostra solo l'ultimo risultato dalla mappa, quindi salta direttamente al iterazione finale – user2374903

+0

@ user2374903 no, non salta all'ultimo, anche se sembra che stia facendo così Non ho guardato da vicino la chiamata "setTimeout", quindi aggiungerò alla mia risposta. – Pointy

+0

Cambiando il il conto da 1 a 0 (che significa che inizia dal primo ciclo) il codice ha funzionato, ma solo mostrando i modelli uno per uno.Il mio errore per non averlo chiarito, l'obiettivo è quello di far comparire tutti i modelli che corrispondono a quel partnumer come una lista sbiadita. – user2374903

24

userei javascript di serie:

for (var m in myMap){ 
    for (var i=0;i<myMap[m].length;i++){ 
    ... do something with myMap[m][i] ... 
    } 
} 

Nota i diversi modi di trattare gli oggetti e gli array.

+1

Perché? E tu hai omesso la chiusura necessaria ... – Bergi

+0

È più veloce e secondo me più pulito. E ho saltato il resto perché non è chiaro per me cosa debba fare. Cos'è #variant? Cosa dovrebbe fare #variant? – Atle

+0

#variant è un ID di un div che verrà mostrato (sbiadito) con le informazioni dalla mappa. Per ogni partnr dovrebbe essere sbiadito in una lista con i modelli corrensponding. – user2374903

1

Non utilizzare gli iteratori per eseguire questa operazione. Mantenere il proprio loop incrementando un contatore nel callback e chiamando ricorsivamente l'operazione sull'elemento successivo.

$.each(myMap, function(_, arr) { 
    processArray(arr, 0); 
}); 

function processArray(arr, i) { 
    if (i >= arr.length) return; 

    setTimeout(function() { 
     $('#variant').fadeOut("slow", function() { 
      $(this).text(i + "-" + arr[i]).fadeIn("slow"); 

      // Handle next iteration 
      processArray(arr, ++i); 
     }); 
    }, 6000); 
} 

Anche se c'è un errore logico nel codice. Stai impostando lo stesso contenitore su più di un valore diverso a (approssimativamente) nello stesso tempo. Forse intendi per ognuno di aggiornare il proprio contenitore.

+0

Grazie per il suggerimento. Ho provato il tuo codice, ma hai ragione sul fatto che c'è un problema con il contenitore. Il codice qui sotto funziona però, ma qui è solo un singolo array di valori: – user2374903

+0

Questo sembra un bel modo per farlo. – Pointy

+0

$ .each (jArray, function (i, val) { setTimeout (function() { $ ('# reklame2'). FadeOut ("slow", function() { $ (this) .text (val) .fadeIn ("slow"); \t \t \t \t \t}); \t \t \t \t \t $ { $ (this) .text (val ('# reklame17') fadeOut ("lento", la funzione (.)) .fadeIn ("slow"); \t \t \t \t \t });} , i * 6000); \t \t \t }); – user2374903

Problemi correlati