Domanda

Ho problemi ordinamento di un array che include elementi indefiniti (un array sparso) in IE7. Questa grande opera in Safari e Firefox, naturalmente, e non ho provato altre versioni di IE, ma qui è un semplice esempio.

<html>
<head>
<script type="text/javascript">
function runscript() {
    var myArray = [{id: 2},
                        undefined,
                        {id: 0},
                        {id: 1},
                        {id: 3},
                        {id: 4},
                        {id: 5}];
    myArray.sort(function compare(a, b) { return a.id - b.id; });
    var output = '';
    for (loop in myArray) {
        output += myArray[loop].id + ' ';
    }
    alert(output);
}
</script>
</head>
<body onLoad="runscript();">
</body>

L'avviso () alla fine mostra inspiegabilmente 0 2 3 4 5 1. Rimozione elemento indefinito dall'array ordina correttamente e il display di avviso 0 1 2 3 4 5.

C'è un modo per risolvere questo in IE7 in modo che possa in modo affidabile ordinare le matrici che includono elementi indefiniti? Non mi interessa dove gli elementi indefiniti finiscono fino a quando gli elementi definiti sono ordinati in modo corretto.

È stato utile?

Soluzione

Provare a cambiare for (loop in myArray) a for (var loop=0; loop<myArray.length; loop++):

function runscript() {
    var myArray = [{id: 2},
                        undefined,
                        {id: 0},
                        {id: 1},
                        {id: 3},
                        {id: 4},
                        {id: 5}];
    myArray.sort(function compare(a, b) { return a.id - b.id; });
    var output = '';
    for (var loop=0; loop<myArray.length; loop++) {
        output += (myArray[loop]||{id: 'undefined'}).id + ' ';
    }
    alert(output);
}
runscript()

quando si utilizza la for (x in object) gli elementi non sono garantiti per essere in ordine. Vedi anche Perché sta usando "for ... in" con matrice di iterazione una cattiva idea?

(È possibile che questo avvisi 0 1 2 3 4 5 undefined)

Modifica non eliminati - Ho testato il sopra e funziona :-P

Altri suggerimenti

Forse è possibile modificare il confronto

myArray.sort(function compare(a, b) { return a.id || 0 - b.id || 0; });

Prima di tutto, la vostra funzione di ordinamento è sbagliata in quanto si prevede di restituire -1, 0 o 1, non un valore booleano.
Utilizzare questa invece

var arr = [.....]
arr.sort((function(a, b){
    if (!a || !b) {
        // Here you choose how to treat undefined/null elements
        return 0;
    }  
    return (a[index].id === b[index].id ? 0 : (a[index].id < b[index].id ? -1 : 1));
})

Ma solo in modo che si sa, quel ciclo tuo sta per lanciare un errore quando si cerca di restituire la proprietà id dall'elemento indefinito. Inoltre, non si dovrebbe mai usare un ciclo for..in per iterare su un array, utilizzare un ciclo con indice di incremento o un po 'inverso come questo

var l = arr.length; 
while (l--) {
    ..
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top