2012-05-13 25 views
9

Ho un array sparso (indici non sono consecutivi) come questo:Javascript scorrendo matrice sparsa

var testArray = { 0: "value1", 5: "value2", 10: "value3", 15: "value4" }; 

Vorrei semplicemente per scorrere ogni elemento, fare alcune cose, ed essere in grado di rompere sotto un determinate condizioni.

Sono abbastanza nuovo per Javascript e non ho trovato un modo corretto per farlo. Ecco cosa ho provato:

  1. Built-in "for..in". Sembra che questo sia not the correct way to iterate through an array

  2. forEach da ECMASCRIPT5. Questo esegue correttamente l'iterazione, ma non posso interrompere il ciclo.

  3. _.each() da Underscore.js. Stesso risultato del # 2.

  4. $.each() da JQuery. Con questo posso rompere restituendo false, ma non scorrerà correttamente. Per l'esempio sopra, invece di iterare a 0, 5, 10, 15, itererà a 0,1,2,3,4,5,6 ... che ovviamente non è quello che mi aspetto.

Quindi la mia domanda è: C'è un modo semplice per iterare una matrice sparsa con la possibilità di rompersi durante il ciclo in Javascript o sarebbe meglio usare un'altra struttura di dati come una tabella hash? Se sì, qualsiasi raccomandazione?

Grazie!

+1

se si guarda attraverso il collegamento fornito nel punto n. 1, il ciclo incorporato per..in è il modo di scorrere le proprietà di un oggetto, che è ciò che si ha – anson

+0

Da quello che ho capito dal collegamento è stato che un problema potrebbe potenzialmente verificarsi se una libreria aggiunge un membro a Array.prototype. Quindi il membro farà parte del ciclo "for..in". – Absolom

+0

Ah ok, il mio esempio non era valido poiché stavo usando un oggetto e non una matrice. Quindi il tuo commento è corretto. – Absolom

risposta

6

Cosa c'è che non va nella sintassi for...in? Si dispone di un oggetto in modo sintassi for...in è completamente valida da usare:

var testArray = { 0: "value1", 5: "value2", 10: "value3", 15: "value4" }; 

for (var key in testArray) { 
    var value = testArray[key]; 

    if (...) { 
    break; 
    } 
} 
+0

Grazie per la risposta. Ma se volessi usare una vera matrice invece di un oggetto? Cosa useresti allora? – Absolom

+0

@Absolom Gli array JS ereditano da Object, quindi funzionerà ancora correttamente. – mikemaccana

+3

Per ... per garantire l'ordine? –

1

for..in non è la cosa peggiore quando si lavora su un hash oggetto. E 'da evitare per l'uso con gli array ([]), ma dovrebbe essere ok qui:

var val; 
for (index in testArray) { 
    if (index == 10) { 
    break; 
    } else { 
    val = testArray[index]; 
    } 
} 
2

prima cosa che dovete baciare-bye-bye è "array". Non c'è un vero Array in ECMAscript (dimenticando gli array di dattilografi e gli inganni binari).

Quindi quello che hai lì è un semplice Object. Per continuare, ti suggerisco di usare .forEach se sei fico con ES5. Se avete bisogno di rompere presto che l'iterazione, si potrebbe desiderare di utilizzare metodi ES5 come .some() o .every(), come:

Object.keys(testArray).some(function(key) { 
    if(+key < 15) {    
     return true; 
    } 

    console.log(key, testArray[key]); 
}); 

Ciò Interruzio l'iterazione quando si incontra una chiave che valore numerico non è inferiore a 15, da restituendo true.

0

Quello che hai non è un array, è solo un oggetto.

È possibile verificare da:

Array.isArray(testArray) 

Per quello che vale, JavaScript ha array che ha detto di essere sparse.Ciò si verifica quando si utilizza l'operatore delete per rimuovere un elemento o modificare la proprietà di lunghezza su maggiore.

Per rispondere alla domanda, per eseguire il ciclo su un oggetto, il modo migliore è Object.keys(obj).forEach().

var o = {"a":3, "b":4}; 

Object.keys(o).forEach(
    function (key) { 
     var val = o[key]; 
     console.log("Key:" + key); 
     console.log("Value:" + val); 
    } 
); 

Il problema possibile con for (var p in o) {…} è che sarà anche ciclo attraverso tutte le proprietà enumerabili di genitore (cioè, la catena di prototipi). Di solito, tuttavia, non si verifica se si definisce l'oggetto in base all'espressione letterale var obj = {...}, che per impostazione predefinita è genitore Object.prototype e non ha proprietà enumerabili.

Problemi correlati