2010-02-24 4 views
10

Lors de la soritng d'un tableau composé d'un mélange de chaînes, de valeurs nulles et de zéros, le résultat n'est pas correctement interprété, les valeurs nulles semblent triées comme si elles étaient nulles cordes. Je l'ai fait (testé sur FireFox):javascript tableau de tri des chaînes mixtes et des valeurs nulles

var arr1 = arr2 = [null, "b", "c", "d", null, "e", 0, "g", null, 0, "h", "i", "l", "m", "n", "o", "p", "ne", "nur", "nimbus"]; 

document.write("SORTED ARRAY:<br>"); 
arr1.sort(); 
arr1.forEach(function(val){document.write(val + "; ")}); 

Et le résultat est:

TRIEE MATRICE: 0; 0; b; c; ré; e; g; h; je; l; m; n; ne; nimbus; nul; nul; nul; nur; o; p; Avez-vous une idée de la façon de rendre la valeur NULL être considérée comme une chaîne vide lors du tri du tableau, de façon à ce qu'ils apparaissent en première position dans l'arry trié avec les zéros.

Merci!

+0

Avez-vous besoin de trier les nombres aussi avant les chaînes? L'ordre lexicographique n'est pas le même que le numérique. Envisagez de commander {100, 15} et {"100", "15"} comme exemple. –

+0

@andras: Non, juste des zéros. –

Répondre

12

Cela va faire ce que vous voulez en convertissant tout en chaînes (en particulier la conversion null à une chaîne vide) et permettant la comparaison de chaînes intégrée de JavaScript faire le travail:

arr2.sort(function(a, b) 
{ 
    /* 
     We avoid reuse of arguments variables in a sort 
     comparison function because of a bug in IE <= 8. 
     See http://www.zachleat.com/web/array-sort/ 
    */ 
    var va = (a === null) ? "" : "" + a, 
     vb = (b === null) ? "" : "" + b; 

    return va > vb ? 1 : (va === vb ? 0 : -1); 
}); 
+0

+1 Pour Ternary Terseness –

+0

Il échouera à trier correctement s'il a des nombres. Vous avez besoin de plus de ternaires. –

+1

@andras Si par correctement vous voulez dire que 20 vient avant 5 le sort par défaut a le même problème –

-1

Le navigateur fait null.toString(); puisque null est un Object, c'est à peu près Object.toString() ... qui retournerait "null"

Passer un paramètre à trier, comme fonction de comparaison [si la fonction retourne quelque chose de plus grand que 0, b est trié inférieur à un]

fonction

serait essentiellement:

comparisonFunc = function(a, b) 
{ 
if((a === null) && (b === null)) return 0; //they're both null and equal 
else if((a === null) && (b != null)) return -1; //move a downwards 
else if((a != null) && (b === null)) return 1; //move b downwards 
else{ 
    //Lexicographical sorting goes here 
} 
} 
set.sort(comparisonFunc); 
-1

Vous pouvez passer le genre un sortfunction

array.sort(sortfunction) 

où sortfunction fait la Compa rison dont vous avez besoin (tri régulier avec des valeurs nulles supérieures aux autres)

1

Utilisez une fonction de commande personnalisée qui gère les valeurs nulles de cette façon.

arr1.sort(function(a, b) { 
    if (a===null) a=''; 
    if (b===null) b=''; 

    if (''+a < ''+b) return -1; 
    if (''+a > ''+b) return 1; 

    return 0; 
}); 
+0

Cette première ligne devrait bien sûr lire: if (a === null) a = ''; – HBP

+0

@Hans Thanks édité –

6
[null, "b", "c", "d", null, "e", 0, "g", null, 0, "h", "i", "l", "m", "n", "o", "p", "ne", "nur", "nimbus"].sort(function (a,b) { 
    return a === null ? -1 : b === null ? 1 : a.toString().localeCompare(b); 
}); 
+0

Ah oui, j'ai oublié 'localeCompare'. +1 –

3

Je ne peux pas encore commenter les réponses, mais je voulais partager mon problème au cas où quelqu'un d'autre utiliserait la solution Tims.

La solution Tims a bien fonctionné. TOUTEFOIS ... il lancerait par intermittence une erreur 'Nombre attendu'. Complètement au hasard.

Ce lien explique le problème et une solution qui a résolu le problème pour moi ...

http://www.zachleat.com/web/array-sort/

espère que cela va quelqu'un le temps que je perdu le débogage/googler!

+0

Intéressant merci pour le partage, j'ai mis à jour les réponses Tim: http://stackoverflow.com/questions/2328562/javascript-sorting-array-of-mixed-strings-and-null-values/2328902#2328902 –

4

Je suis tombé sur ce fil à la recherche d'une réponse similaire rapide et sale, mais il n'a pas touché à ce dont j'avais réellement besoin. "Comment traiter les nulls", les faire flotter vers le haut ou le bas, etc.C'est ce que je suis venu avec:

var list = [0, -1, 1, -1, 0, null, 1]; 

var sorter = function(direction){ 

    // returns a sort function which treats `null` as a special case, either 'always higher' (1) 
    // or 'always lower' (-1) 

    direction = direction || 1; 
    var up = direction > 0; 

    return function(a, b){ 

     var r = -1, 
      aa = a == null ? undefined : a, 
      bb = b == null ? undefined : b, 
      careabout = up ? aa : bb 
     ; 

     if(aa == bb){ 
      r = 0; 
     }else if(aa > bb || careabout == undefined){ 
      r = 1 
     } 
     return r; 

    } 

} 

var higher = [].concat(list.sort(sorter(1)));  
var lower = [].concat(list.sort(sorter(-1))); 

console.log(lower[0] === null, lower); 
console.log(higher[higher.length - 1] === null, higher); 

// then, something that sorts something in a direction can use that direction to 
// determine where the nulls end up. `list` above ranged from negative-one to one, 
// with mixed zero and null values in between. If we want to view that list 
// from highest value to descending, we'd want the nulls to be treated as 
// 'always lower' so they appear at the end of the list. 
// If we wanted to view the list from lowest value to highest value we'd want the 
// nulls to be treated as `higher-than-anything` so they would appear at the bottom 
// list. 

var sortThisArray = function(arr, direction){ 
    var s = sorter(direction); 
    return arr.sort(function(a,b){ 
     return direction * s(a,b) 
    }); 
} 

console.log(sortThisArray(list, 1)); 
console.log(sortThisArray(list, -1)); 
2

Je ne peux pas ajouter un commentaire encore @ commentaire de robert, mais voici une expansion sur @ robert de pour ajouter le support booléenne:

[null, "b", "c", "d", null, "e", 0, undefined, "g", null, 0, "h", "i", true, "l", "m", undefined, "n", "o", "p", false, "ne", "nur", "nimbus"].sort(function (a,b) { 
    if (a === b) { return 0; } 
    if (a === null) { 
     return -1; 
    } else if (b === null) { 
     return 1; 
    } else if (typeof a === 'string') { 
     return a.localeCompare(b); 
    } else if (typeof a === 'number' || typeof a === 'boolean') { 
     if (a < b) return -1; 
     if (a > b) return 1; 
    } 
    return 0; 
}); 

aussi, par spécification JS, undefineds est toujours initialisé à la fin du tableau ...

Questions connexes