Reputation: 1372
Can someone explain the code below:
var values = [213, 16, 2058, 54, 10, 1965, 57, 9];
values.sort(function(value1,value2){ return value2 - value1; });
I am not able to understand how value1 and value2 are loaded from array values, and how does it reverse the sorting result.
Upvotes: 1
Views: 512
Reputation: 39542
The sort function does the following:
return value2 - value1;
Let's make it a bit more verbose so we can see what is going on:
var values = [213, 16, 2058, 54, 10, 1965, 57, 9];
values.sort(function(value1,value2){
console.log(value2 + ' - ' + value1 + ' = ' + (value2 - value1) + ' | (' + (value2 - value1 > 0 ? 'positive | ' + value2 + ' should be before ' + value1 : 'negative | ' + value2 + ' should be after ' + value1) + ')');
return value2 - value1;
});
Output:
16 - 213 = -197 | (negative | 16 should be after 213)
2058 - 16 = 2042 | (positive | 2058 should be before 16)
2058 - 213 = 1845 | (positive | 2058 should be before 213)
54 - 16 = 38 | (positive | 54 should be before 16)
54 - 213 = -159 | (negative | 54 should be after 213)
10 - 16 = -6 | (negative | 10 should be after 16)
1965 - 10 = 1955 | (positive | 1965 should be before 10)
1965 - 16 = 1949 | (positive | 1965 should be before 16)
1965 - 54 = 1911 | (positive | 1965 should be before 54)
1965 - 213 = 1752 | (positive | 1965 should be before 213)
1965 - 2058 = -93 | (negative | 1965 should be after 2058)
57 - 10 = 47 | (positive | 57 should be before 10)
57 - 16 = 41 | (positive | 57 should be before 16)
57 - 54 = 3 | (positive | 57 should be before 54)
57 - 213 = -156 | (negative | 57 should be after 213)
9 - 10 = -1 | (negative | 9 should be after 10)
If you do the following with all values you'll notice that if value2
is larger than value1
the result will always be positive, and it'll be shifted forwards in the array - essentially ending up with a reversely sorted array.
Upvotes: 3
Reputation: 1437
Sorting arrays in JavaScript is done via the method array.sort(), a method that's probably as much misunderstood as it is underestimated. While calling sort() by itself simply sorts the array in lexicographical (aka alphabetical) order, the sky's really the limit once you go beyond the surface. Sorting an array in lexicographical order
Sorting an array lexicographically (aka "alphabetically" or in dictionary order) is easy to do. Just call array.sort() without any parameters passed in:
//Sort alphabetically and ascending:
var myarray=["Bob", "Bully", "Amy"]
myarray.sort() //Array now becomes ["Amy", "Bob", "Bully"]
Notice that the order is ascending. To make it descending instead, the simplest way is to enlist the help of another Array method in combination, array.reverse():
//Sort alphabetically and descending:
var myarray=["Bob", "Bully", "Amy"]
myarray.sort()
myarray.reverse() //Array now becomes ["Bully", "Bob", "Amy"]
Now, before you start feeling comfortable, consider what happens if we call array.sort() on an array consisting of numbers:
var myarray=[7, 40, 300]
myarray.sort() //Array now becomes [300,40,7]
Although 7 is numerically smaller than 40 or 300, lexicographically, it is larger, so 7 appears at the very right of the sorted array. Remember, by default array.sort() sorts its elements in lexicographical order.
And there you have it with array.sort() in terms of its basic usage. But there's a lot more to this method than meets the eye. Array.sort() accepts an optional parameter in the form of a function reference that pretty much lets you sort an array based on any custom criteria, such as sort an array numerically or shuffle it (randomize the order of its elements). Passing in a function reference into array.sort() As touched on already, array.sort() accepts an optional parameter in the form of a function reference (lets call it sortfunction). The format of this function looks like this:
array.sort(sortfunction)
function sortfunction(a, b){
//Compare "a" and "b" in some fashion, and return -1, 0, or 1
}
When such a function is passed into array.sort(), the array elements are sorted based on the relationship between each pair of elements "a" and "b" and the function's return value. The three possible return numbers are: <0 (less than 0), 0, or >0 (greater than 0):
Less than 0: Sort "a" to be a lower index than "b" Zero: "a" and "b" should be considered equal, and no sorting performed. Greater than 0: Sort "b" to be a lower index than "a".
To sort an array numerically and ascending for example, the body of your function would look like this:
function sortfunction(a, b){
return (a - b) //causes an array to be sorted numerically and ascending
}
More on this below. Sorting an array in numerical order
To sort an array in numerical order, simply pass a custom sortfunction into array.sort() that returns the difference between "a" and "b", the two parameters indirectly/ automatically fed into the function:
//Sort numerically and ascending:
var myarray=[25, 8, 7, 41]
myarray.sort(function(a,b){return a - b}) //Array now becomes [7, 8, 25, 41]
This works the way it does because whenever "a" is less than "b", a negative value is returned, which results in the smaller elements always appearing to the left of the larger ones, in other words, ascending.
Sort an array numerically but descending isn't much different, and just requires reversing the two operands "a" and "b":
//Sort numerically and descending:
var myarray=[25, 8, 7, 41]
myarray.sort(function(a,b){return b - a}) //Array now becomes [41, 25, 8, 71]
Shuffling (randomizing) the order of an array
To randomize the order of the elements within an array, what we need is the body of our sortfunction to return a number that is randomly <0, 0, or >0, irrespective to the relationship between "a" and "b". The below will do the trick:
//Randomize the order of the array:
var myarray=[25, 8, "George", "John"]
myarray.sort(function() {return 0.5 - Math.random()}) //Array elements now scrambled
As you can see, there is a lot more to array.sort() than many may think. In fact, you can even sort arrays that contain more than just primitive values, but objects with properties. Lets see that next.
http://www.javascriptkit.com/javatutors/arraysort.shtml
Upvotes: 1
Reputation: 1074575
The Array#sort
function calls the callback you give it (called a comparator) repeatedly to compare two values from the array. It does this as necessary while sorting the array. So the sorting logic is in Array#sort
, but the comparison logic is in the comparator function you give it.
The comparator is expected to return one of three values:
0
if the two arguments are equal< 0
if the first argument is "less than" the second one> 0
if the first argument is "greater than" the second oneThe number of times sort
calls your comparator, and the order of those calls, is not dictated by the specification.
Your specific comparator is comparing numbers, and so it's quite simple: It just returns value2 - value1
. This means if value1
is less than value2
, the comparator will return a positive number; if value1
is equal to value2
, the comparator will return 0
; and if value1
is greater than value2
, it will return -1
. So this particular comparator sorts in reverse numeric order (largest numbers first).
Upvotes: 1
Reputation: 5221
For almost any sorting function, you will need to compare two values at some point of time to determine which is larger and which is smaller. How many comparisons you make is obviously dependent on the efficiency of sorting algorithm.
You can provide this behavior in javascript and many other languages. Any function you give in sort()
is called a comparator and in expected to return one of the following three values:
Upvotes: 0
Reputation: 7511
value1
and value2
are variables of the function you create. That function is passed to the sort
function, who is responsible for sorting the array.
The sort
function works out what order the elements should be on by calling your provided function on pairs of elements. Depending on the result (negative or positive), the sort
function orders them.
In this case, it returns positive if value2
is larger than value1
, meaning that it is sorted from largest to smallest.
Upvotes: 1