简体   繁体   中英

Sorting numerical arrays in JavaScript

I am trying to make sense of a snippet of JS code that gets a numeric array and sorts it:

var msg = document.getElementById("message");

var v = [30,2,1,9,15];
msg.innerHTML += "<p><strong>Original order:</strong> [" + v + "]<p>";

v.sort(sortLowToHigh);
msg.innerHTML += "<p><strong>After sorting:</strong> [" + v + "]<p>";

function sortLowToHigh(a, b) {
    return a - b;
}

Output:

Original order: [30,2,1,9,15]

After sorting: [1,2,9,15,30]

I realize this much that the sort() function, when used alone, converts the array elements to strings and the result of that sorting would be undesirable.

But I don't know how and based on what process the sortLowToHigh trains the sort method in sorting the numeric values in ascending order.

sort accepts a compare function. All the function needs to do is compare two values and return a value less than 0 if a is considered smaller than b, bigger than 0 if a is larger than b, or 0 if they are equal. Using that comparison, the sort function handles the actual sorting.

For numbers, this compare function is easy. You just return a - b , and you got your return value of <0 , 0 or >0 .

When you give sort a function (called a comparator ), sort doesn't make any assumptions about the values (or convert them to anything) at all. It just calls the function you give it repeatedly to compare pairs of elements (call them a and b ), and uses the function's return value to determine how to order those two elements in the result: If it's 0 , a and b are equal; if it's positive, b should come after a (eg, b is "greater than" a ); if it's negative, b should come before a (eg, b is "less than a ). So by subtracting a from b , the sortLowToHigh returns the appropriate values.

The convert-to-string behavior you mention only applies when you don't give sort a comparator to use.

This is covered (in turgid prose) by §15.4.4.11 of the spec.

The order of the calls to the comparator is completely up to the implementation, and different implementations may use different sorting algorithms, so some JavaScript engines may call the comparator more or fewer times, or in a different order, compared to others. For example, given this:

 var v = [30,2,1,9,15]; v.sort(function(a, b) { snippet.log("a = " + a + ", b = " + b); }); snippet.log(v.join(", ")); 
 <!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> <script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script> 

The current version of Chrome outputs:

a = 30, b = 2
a = 2, b = 1
a = 1, b = 9
a = 9, b = 15
30, 2, 1, 9, 15

...but the current version of Firefox outputs

a = 30, b = 2
a = 2, b = 1
a = 9, b = 15
a = 1, b = 9
30, 2, 1, 9, 15

They both get the same result, of course, or one of them would be violating the spec, but it's fun to see that the order of calls really does vary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM