Чтобы ответить на ваш вопрос о том, как работает функция сортировки, я объясню это подробно.Как было сказано в большинстве ответов здесь, вызов только sort()
для массива отсортирует ваш массив, используя строки.Преобразование ваших целых чисел в строки, а также.Blech!
Если вы считаете свои предметы символами, а не числами, имеет смысл, что они будут отсортированы таким образом.Хороший способ убедиться в этом - назначить буквы вашим номерам.
//0 = a
//1 = b
//2 = c
//4 = e
//5 = f
//These two arrays are treated the same because they're composed of strings.
var nums = ["10", "5", "40", "25", "100", "1"];
var chars = ["ba", "f", "ea", "cf", "baa", "b"];
//Here we can see that sort() correctly sorted these strings. Looking at the
//alphabetical characters we see that they are in the correct order. Looking
//at our numbers in the same light, it makes sense that they are sorted
//this way as well. After all, we did pass them as strings to our array.
chars.sort(); //["b", "ba", "baa", "cf", "ea", "f"]
nums.sort(); //["1", "10", "100", "25", "40", "5"]
//The bad part of sort() comes in when our array is actually made up of numbers.
var nums = [10, 5, 40, 25, 100, 1];
nums.sort(); //[1, 10, 100, 25, 40, 5]
//As a result of the default sorting function converting numbers to strings
//before sorting, we get an unwanted result. We can fix this by passing in our
//own function as a parameter to sort().
Вы можете управлять сортировкой массива, передавая свою собственную функцию в качестве параметра функции sort()
.Это хорошо, но если вы не знаете, как работает функция sort()
, она действительно не принесет вам пользы.
sort()
будет вызывать вашу функцию несколько раз для перестановки массива.В зависимости от того, что возвращается из вашей функции, sort()
сообщает, что делать с элементами в массиве.Если возвращается отрицательное число или 0, перестановка не происходит.Если возвращается положительное число, два элемента меняются местами.sort()
следит за тем, какие числа он уже тестировал, поэтому он не заканчивает тестирование чисел позже, после того как он переключил элементы.Если sort()
переупорядочивает элементы, он вернется на одну позицию назад и увидит, проверял ли он эти два элемента ранее.Если этого не произойдет, он проверит их.Если это так, он продолжит работу без запуска вашей функции.
Сортировка чисел
Давайте рассмотрим простой пример, и я проведу вас через него:
var arr = [50, 90, 1, 10, 2];
arr = arr.sort(function(current, next){
//My comments get generated from here
return current - next;
});
//1 : current = 50, next = 90
// : current - next (50 - 90 = -40)
// : Negative number means no re-arranging
// : Array now looks like [50, 90, 1, 10, 2]
//
//2 : current = 90, next = 1
// : current - next (90 - 1 = 89)
// : Positive number means sort() will switch these positions in the array
// : Array now looks like [50, 1, 90, 10, 2]
//
//If sort() didn't backtrack, the next check would be 90 and 10, switch those
//positions, check 90 and 2, and switch again. Making the final array
//[50, 1, 10, 2, 90], not sorted. But lucky for us, sort() does backtrack.
//
//3 : current = 50, next = 1
// : current - next (50 - 1 = 49)
// : Positive number means sort() will switch these positions in the array
// : Array now looks like [1, 50, 90, 10, 2]
//
//If sort() wasn't smart, it would now check 50 and 90 again. What a waste!
//But lucky for us again, sort() is smart and knows it already made this
//check and will continue on.
//
//4 : current = 90, next = 10
// : current - next (90 - 10 = 80)
// : Positive number means sort() will switch these positions in the array
// : Array now looks like [1, 50, 10, 90, 2]
//
//sort() backtracks one position and sees that it has not checked 50 and 10
//
//5 : current = 50, next = 10
// : current - next (50 - 10 = 40)
// : Positive number means sort() will switch these positions in the array
// : Array now looks like [1, 10, 50, 90, 2]
//
//sort() backtracks one position and sees that it has not checked 1 and 10
//
//6 : current = 1, next = 10
// : current - next (1 - 10 = -9)
// : Negative number means no re-arranging
// : Array now looks like [1, 10, 50, 90, 2]
//
//sort() remembers that it already checked 10 and 50 so it skips ahead
//sort() remembers that it already checked 50 and 90 so it skips ahead
//
//7 : current = 90, next = 2
// : current - next (90 - 2 = 88)
// : Positive number means sort() will switch these positions in the array
// : Array now looks like [1, 10, 50, 2, 90]
//
//sort() backtracks one position and sees that it has not checked 50 and 2
//
//8 : current = 50, next = 2
// : current - next (50 - 2 = 48)
// : Positive number means sort() will switch these positions in the array
// : Array now looks like [1, 10, 2, 50, 90]
//
//sort() backtracks one position and sees that it has not checked 10 and 2
//
//9 : current = 10, next = 2
// : current - next (10 - 2 = 8)
// : Positive number means sort() will switch these positions in the array
// : Array now looks like [1, 2, 10, 50, 90]
//
//sort() backtracks one position and sees that it has not checked 1 and 2
//
//10: current = 1, next = 2
// : current - next (1 - 2 = -1)
// : Negative number means no re-arranging
// : Array now looks like [1, 2, 10, 50, 90]
//
//sort() remembers that it already checked 2 and 10 so it skips ahead
//sort() remembers that it already checked 10 and 50 so it skips ahead
//sort() remembers that it already checked 50 and 90 so it skips ahead
//sort() has no more items to check so it returns the final array
//which is [1, 2, 10, 50, 90]
Если вы хотите, чтобы массив упорядочивался в порядке убывания [90, 50, 10, 2, 1]
, вы можете просто изменить оператор возврата с return current - next;
на return next - current;
следующим образом:
var arr = [50, 90, 1, 10, 2];
arr = arr.sort(function(current, next){
//My comments get generated from here
return next - current;
});
//1 : current = 50, next = 90
// : next - current (90 - 50 = 40)
// : Positive number means sort() will switch these positions in the array
// : Array now looks like [90, 50, 1, 10, 2]
//
//2 : current = 50, next = 1
// : next - current (1 - 50 = -49)
// : Negative number means no re-arranging
// : Array now looks like [90, 50, 1, 10, 2]
//
//etc.
Не имеет значения, является ли ваш массивсостоит из «строковых чисел» "5"
или просто чисел 5
при использовании собственной функции для сортировки чисел.Потому что, когда JavaScript выполняет математику, он рассматривает «строковые числа» как числа.т.е. "5" - "3" = 2
Сортировка строк
Когда вы сортируете строки, вы можете сравнивать их, используя операторы >
и <
(больше и меньше).Оператор «больше» сортирует строку по возрастанию (AZ, 1-9), а оператор «меньше» сортирует по убыванию (ZA, 9-1).В разных браузерах используются разные алгоритмы сортировки, поэтому при сортировке по строкам необходимо убедиться, что вы возвращаете либо 1, либо -1, а не true или false.
Например, это работает в Chrome и FF, но не в IE:
var arr = ['banana', 'orange', 'apple', 'grape'];
arr = arr.sort(function(current, next){
return current > next;
});
Чтобы убедиться, что алгоритм сортировки работает в любом браузере, используйте троичный оператор.
var arr = ['banana', 'orange', 'apple', 'grape'];
arr = arr.sort(function(current, next){
return current > next? 1: -1;
});
При изменении способа сортировки (в порядке возрастания или убывания)), помимо смены операторов, вы можете оставить тот же оператор и переключать переменные current
и next
, как мы это делали при сортировке чисел.Или, поскольку мы используем троичный оператор, вы можете переключать 1
и -1
.
Сортировка объектов
Вот еще один изящный прием, который я решил добавить сюда.Вы можете сортировать объекты, если вы добавляете их в массив и используете их для сравнения.Вот пример.
var arr = [
{id: 2, name: 'Paul'},
{id: 1, name: 'Pete'}
];
//sort numerically
arr = arr.sort(function(current, next){
return current.id - next.id;
});
//Array now looks like [{id: 1, name: 'Pete'}, {id: 2, name: 'Paul'}]
//sort alphabetically
arr = arr.sort(function(current, next){
return current.name > next.name? 1: -1;
});
//Array now looks like [{id: 2, name: 'Paul'}, {id: 1, name: 'Pete'}]
Резюме
Сортировка чисел в по возрастанию (1, 2, 3 ...) : function(a, b){return a - b;}
в в порядке убывания (9, 8, 7 ...) : function(a, b){return b - a;}
для сортировки строк в в порядке возрастания (A, B, C ...) : function(a, b){return a > b? 1: -1;}
в в порядке убывания (Z, Y, X ...) : function(a, b){return b > a? 1: -1;}
Для сортировки объектов добавьте их в массив,затем сортируйте по ключу: function(a, b){return a.key - b.key;}