vote up 3 vote down star

When soritng an array made of a mix of strings, null values and zeros, i get the result not properly as exptected, null values seem to get sorted as if they were 'null' strings. I did this (tested on FireFox):

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 1:<br>");
arr1.sort();
arr1.forEach(function(val){document.write(val + "; ")});

And the result is:

SORTED ARRAY 1: 0; 0; b; c; d; e; g; h; i; l; m; n; ne; nimbus; null; null; null; nur; o; p;

Do you have an idea of how to make the null value be considered like empty string during the sorting of the array, so that they appear 1st in the sorted arry along with the zeros.

Thanks!

flag

71% accept rate
Do you need numbers sorted as well before strings? Lexicographic order is not the same as numeric. Consider ordering { 100, 15 } and { "100", "15" } as an example. – andras Feb 24 at 20:09
@andras: No, just zeros. – Marco Demaio Feb 25 at 15:54

5 Answers

vote up 3 vote down check

This will do what you want by converting everything to strings (in particular converting null to an empty string) and allowing JavaScript's built-in string comparison do the work:

arr2.sort( function(a, b) {
    a = (a === null) ? "" : "" + a;
    b = (b === null) ? "" : "" + b;
    return a > b ? 1 : ( a === b ? 0 : -1 );
} );
link|flag
+1 For Ternary Terseness – Alexandre Jasmin Feb 24 at 19:43
This will fail to sort properly if he has numbers. You need some more ternaries. – andras Feb 24 at 19:56
1  
@andras If by properly you mean that 20 comes before 5 the default sort has the same issue – Alexandre Jasmin Feb 24 at 20:06
@andras, @Alexandre: The original question does say the array has zeros, strings and nulls so I'm not sure correctly handling numbers is required, but I take your point. – Tim Down Feb 24 at 20:10
@Tim: sounds great thanks! What about doing: a = a || ""; b = b || ""; – Marco Demaio Feb 25 at 15:54
show 1 more comment
vote up 1 vote down
[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);
});
link|flag
Ah yes, I forgot about localeCompare. +1. – Tim Down Feb 25 at 16:20
vote up 0 vote down

You can pass the sort a sortfunction

array.sort(sortfunction)

where sortfunction does the comparison you need (regular sorting with null values being greater than others)

link|flag
vote up 0 vote down

The browser is doing null.toString(); since null is an Object, this is pretty much Object.toString()... which would return "null"

Pass in a parameter to sort, as your comparison function [if the function returns something greater than 0, b is sorted lower than a]

function would basically be:

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);
link|flag
vote up 0 vote down

Use a custom ordering function that handles null values this way.

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;
});
link|flag
That first line should of course read: if (a===null) a=''; – Hans B PUFAL Feb 24 at 18:57
@Hans Thanks edited – Alexandre Jasmin Feb 24 at 19:02

Your Answer

Get an OpenID
or
never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.