Sunday, May 19, 2024
 Popular · Latest · Hot · Upcoming
-1
rated 0 times [  1] [ 2]  / answers: 1 / hits: 21361  / 11 Years ago, mon, september 30, 2013, 12:00:00

I'm trying to sort an array of values that can be a mixture of numeric or string values (e.g. [10,20,null,1,bar,-2,-3,null,5,foo]). How can I sort this array such that




  • null values are always placed last (regardless of sorting order, see jsFiddle)

  • negative numbers are sorted correctly (i.e. they are less than positive numbers and sort correctly amongst themselves)



? I made a jsFiddle with detailed numeric and string examples (using localeCompare and the numeric option), but will paste the numeric version of my sorting algorithm below as a starting point.



// Sorting order
var order = asc; // Try switching between asc and dsc

// Dummy arrays
var numericArr = [10,20,null,1,-2,-3,null,5];

// Sort arrays
$(.output1).append(numericArr.toString());
numericArr.sort(sortByDataNumeric);
$(.output2).append(numericArr.toString());

// Numeric sorting function
function sortByDataNumeric(a, b, _order) {

// Replace internal parameters if not used
if (_order == null) _order = order;

// If values are null, place them at the end
var dflt = (_order == asc ? Number.MAX_VALUE : -Number.MAX_VALUE);

// Numeric values
var aVal = (a == null ? dflt : a);
var bVal = (b == null ? dflt : b);
return _order == asc ? (aVal - bVal) : (bVal - aVal);
}


The problem with my string sorting algorithm (see jsFiddle) is that I can't find a way to always place null values last and negative values aren't correctly sorted within themselves (e.g. -3 should be less than -2)



Edit



To answer the comments, I expect [10,20,null,1,bar,-2,-3,null,5,foo] to sort to [-3,-2,1,5,10,20,bar,foo,null,null]


More From » sorting

 Answers
16

You should first check to see if either value is null and return the opposite value.




On a side note:


For your default _order value, you should check if the parameter is undefined instead of comparing its value to null. If you try to compare something that is undefined directly you will get a reference error:


(undefinedVar == null) // ReferenceError: undefinedVar is not defined

Instead, you should check if the variable is undefined:


(typeof undefinedVar == "undefined") // true

Also, it's probably a better idea to wrap your compare function in a closure instead of relying on a global order variable.


Sometime like:


[].sort(function(a, b){ return sort(a, b, order)})

This way you can sort at a per-instance level.




http://jsfiddle.net/gxFGN/10/


JavaScript


function sort(a, b, asc) {
var result;

/* Default ascending order */
if (typeof asc == "undefined") asc = true;

if (a === null) return 1;
if (b === null) return -1;
if (a === null && b === null) return 0;

result = a - b;

if (isNaN(result)) {
return (asc) ? a.toString().localeCompare(b) : b.toString().localeCompare(a);
}
else {
return (asc) ? result : -result;
}
}

[#75324] Sunday, September 29, 2013, 11 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
leslijessalyng

Total Points: 650
Total Questions: 85
Total Answers: 109

Location: Croatia
Member since Mon, Sep 6, 2021
3 Years ago
leslijessalyng questions
Fri, Feb 21, 20, 00:00, 4 Years ago
Tue, Jul 30, 19, 00:00, 5 Years ago
Fri, Jul 5, 19, 00:00, 5 Years ago
Wed, Mar 13, 19, 00:00, 5 Years ago
;