Sort an array so that null values always come last
I need to sort an array of strings, but I need it so that null is always last. For example, the array:
var arr = [a, b, null, d, null]
When sorted ascending I need it to be sorted like [a, b, d, null, null]
and when sorted descending I need it to be sorted like [d, b, a, null, null]
.
Is this possible? I tried the solution found below but it's not quite what I need.
How can one compare string and numeric values (respecting negative values, with null always last)?
Check out .sort()
and do it with custom sorting.
Example
function alphabetically(ascending) {
return function (a, b) {
// equal items sort equally
if (a === b) {
return 0;
}
// nulls sort after anything else
else if (a === null) {
return 1;
}
else if (b === null) {
return -1;
}
// otherwise, if we're ascending, lowest sorts first
else if (ascending) {
return a < b ? -1 : 1;
}
// if descending, highest sorts first
else {
return a < b ? 1 : -1;
}
};
}
var arr = [null, 'a', 'b', null, 'd'];
console.log(arr.sort(alphabetically(true)));
console.log(arr.sort(alphabetically(false)));
Use a custom compare function that discriminates against null
values:
arr.sort(function(a, b) {
return (a===null)-(b===null) || +(a>b)||-(a<b);
});
For descending order of the non-null values, just swap a
and b
in the direct comparison:
arr.sort(function(a, b) {
return (a===null)-(b===null) || -(a>b)||+(a<b);
});
Ascending
arr.sort((a, b) => (a != null ? a : Infinity) - (b != null ? b : Infinity))
Descending
arr.sort((a, b) => (b != null ? b : -Infinity) - (a != null ? a : -Infinity))
(For descending order if you don't have negative values in the array, I recommend to use 0 instead of -Infinity)
The simplest approach is to handle null
first, then deal with non-null cases based on the desired order:
function sortnull(arr, ascending) {
// default to ascending
if (typeof(ascending) === "undefined")
ascending = true;
const multiplier = ascending ? 1 : -1;
const sorter = function(a, b) {
if (a === b) // identical? return 0
return 0;
else if (a === null) // a is null? last
return 1;
else if (b === null) // b is null? last
return -1;
else // compare, negate if descending
return a.localeCompare(b) * multiplier;
}
return arr.sort(sorter);
}
const arr = ["a", "b", null, "d", null];
console.log(sortnull(arr)); // ascending ["a", "b", "d", null, null]
console.log(sortnull(arr, true)); // ascending ["a", "b", "d", null, null]
console.log(sortnull(arr, false)); // descending ["d", "b", "a", null, null]