Методы массивов: map, sort
Метод map
Метод map
создает новый массив из элементов, которые будут являться результатами выполнения callback-функции.
У метода map
имеется только один аргумент, который является callback-функцией. У этой функции имеется 3 аргумента, по аналогии с методами описанными выше:
Первый аргумент – текущей элемент (элемент на текущей итерации).
Второй аргумент – индекс этого элемента в массиве.
Третий аргумент – сам массив.
Повторюсь, callback-функция может быть как обычной (function declaration), так и стрелочной (arrow function).
Пример использования:
const numbers = [2, 5, 7, 9]; const results = numbers.map(n => n ** 5); results; //[32, 3125, 16807, 59049]
Из исходного массива numbers
, с помощью метода map
мы создали новый массив, в котором каждое число было возведено в 5-ую степень.
Метод sort
Метод sort
, как несложно догадаться по названию – сортирует массив. При этом, сортирует он его "на месте", что означает, что изменяется исходный массив. Плюсом к этому этот метод еще и возвращает тот же самый массив, т.е. результат выполнения данного метода можно еще и в другую переменную запихнуть (но это делается крайне редко).
Самый простой пример, который можно придумать, отсортировать числа, например, по возрастанию, но мы начнем не с них, а с буковок:
const characters = ['d', 'z', 'a', 'c', 'y']; characters.sort(); characters; //['a', 'c', 'd', 'y', 'z']
Как видишь, метод расположил буквы в соответствии с правильными их расположением в латинском алфавите. Но что же будет, если применить метод sort
к массиву с числами? Глянем:
const numbers = [45, 4, 2, 1, -50, 300, 0]; numbers.sort(); numbers; //[-50, 0, 1, 2, 300, 4, 45]
И казалось бы, что может пойти не так.... Но, всмотрись внимательно и увидишь, что значение 300 заняло далеко не свое место в этом танце =) Почему так? Потомукта. А если серьезно, то случилось это по той причине, что метод sort по умолчанию при работе с элементами массива преобразует их (элементы) к строковому типу и для сортировки применяется лексикографический порядок. А если сравнивать строки, то строка 300
будет больше чем строка 4
. Чтобы такой чепухи не было, нам нужно задать свой порядок сортировки, со своим Блэкджеком и шлюпками.
Ты же заметил, что мы не передавали никакого аргумента в метод sort
, а они у него есть. И да, это снова callback-функция. Если ты ее передашь, то она и будет (должна) задавать правила сортировки для массива.
Главное правило callback-функции для данного метода – для пары значений она должна возвращать:
1
(или любое положительное число) – если первое значение больше второго;0
– если значения равны;-1
(или любое отрицательное число) – если первое значение меньше второго.
Теперь подкрепим понимание кодом:
const numbers = [45, 4, 2, 1, -50, 300, 0]; function compare(a, b) { if (a > b) return 1; if (a === b) return 0; if (a < b) return - 1; }; numbers.sort(compare); numbers; //[-50, 0, 1, 2, 4, 45, 300]
Вот оно, чудо из всех чудес! Теперь сортировка отработала совершенно правильно.
Что же мы поменяли? Да в целом, ничего. Мы создали функцию, в которой описали при каких условиях и что возвращать используя правило выше. И эту функцию мы передали в аргумент метода. И все заработало как часы.
Конкретно данный случай можно еще и упростить, если использовать стрелочную функцию и немного включить логику. Смотри:
const numbers = [45, 4, 2, 1, -50, 300, 0]; numbers.sort((a, b) => a - b); numbers; //[-50, 0, 1, 2, 4, 45, 300]
Воу!!! Код колосально сократился, но чего же мы такого тут поменяли?
Во-первых, мы ввели стрелочную функцию, что в львиной доле случаев делает код короче автоматически.
Во-вторых, посмотри на эту функцию: (a, b) => a - b
. Здесь так же фигурируют a
и b
, как и в примере выше и мы возвращаем их разницу. Зачем?
Ты не забыл о главном правиле? Функция должна вернуть 1(или любое положительное число)
, 0
или -1(или любое отрицательное число)
.
Именно это тут и вернется. Если числа будут равны, то результат a - b
даст нам значение 0
. Если a > b
, то нам вернется положительное число, если a < b
, то вернутся отрицательное число. Таким образом правило у нас исполняется и метод работает как нужно.