В JavaScript массивы используются повсеместно.

К счастью для нас, уже существует множество функций, которые позволяют нам работать с массивами многими полезными способами, и некоторые из них известны как методы обработки коллекций, некоторые из них: сопоставление, уменьшение, поиск, фильтрация и т. д.

Это функции, которые позволяют нам обрабатывать каждый элемент массива и что-то с ним делать, это может быть его печать, сравнение, суммирование и так далее.

Итак, зачем кому-то писать свои собственные функции, если они уже доступны в JavaScript «бесплатно»? Ну и это больше актуально для начинающих программистов, есть два основных плюса попрактиковаться в написании этих функций самостоятельно.

  1. Вы получите более глубокое понимание встроенных в JavaScript методов обработки коллекций.
  2. Вы закончите эту практику более глубоким пониманием функций обратного вызова.

Несмотря на то, что эта статья была написана в основном для начинающих программистов, каждый может получить дополнительную практику, если попытается это сделать.

Мы собираемся написать метод map, а после этого вы можете попробовать сделать остальные методы, следуя аналогичному подходу. По данным МДН,

"метод map() создает новый массив, заполненный результатами вызова предоставленной функции для каждого элемента вызывающего массива"

В этом определении есть два важных пункта:

  1. Создает новый массив
  2. Вызывает предоставленную функцию

Это означает, что наша функция должна получить два параметра: массив и функцию.

Приступим к определению нашей функции:

function myMap(array, callback) {

}

Первый шаг выполнен! Мы получаем массив в одноименном параметре и функцию, которую нужно вызывать для каждого элемента массива в переменной с именем callback.

Теперь, после того как функция создаст новый массив, этот массив будет возвращаемым значением функции. Добавим это:

function myMap(array, callback) {
    const newArray = [];
    return newArray;
}

И последним шагом должен быть вызов предоставленной функции для каждого элемента вызывающего массива.

for (let i = 0; i < array.length; i++) {
    newArray[i] = callback(array[i]);
}

Таким образом, мы берем каждый элемент массива, вызываем функцию обратного вызова, отправляющую этот элемент в качестве аргумента, и сохраняем результат этого процесса, что бы он ни делал, в той же позиции, но во вновь созданном массиве. В конце этого цикла for будет другой массив с таким же количеством элементов, но уже обработанный функцией обратного вызова. Это завершает наш собственный метод карты.

Но поскольку массивы и объекты могут использовать один и тот же метод карты, как мы можем изменить нашу функцию, чтобы она также принимала объекты?

Прежде чем мы это сделаем, давайте изменим объявление нашей функции на более общее и примем либо массив, либо объект:

function myMap(collection, callback) {

Таким образом, теперь мы ясно даем понять, что получаем набор элементов, они могут быть массивом или объектом, поэтому мы меняем имя первого параметра. Теперь мы можем добавить этот фрагмент кода перед обработкой массива.

let array;
if (Array.isArray(collection)) {
    array = collection;
} else {
    array = Object.values(collection);
}

Здесь мы проверяем, является ли коллекция элементов уже массивом, и нам больше нечего делать, кроме как присвоить коллекцию нашему общему массиву переменных. Если это не массив, это означает, что это объект, поэтому нам нужно преобразовать значения в объекте в массив, мы делаем это, используя метод values ​​, он вернет все значения в объект.

Примечание. Как видите, мы объявляем переменную массив вне оператора if; это важно, потому что если мы объявим его внутри, мы не сможем использовать его снаружи, потому что его область действия будет ограничена оператором if.

Наконец, наша функция завершена, и она выглядит так:

function myMap(collection, callback) {
    let array;
    if (Array.isArray(collection)) {
        array = collection;
    } else {
        array = Object.values(collection);
    }
    const newArray = [];
    for (let i = 0; i < array.length; i++) {
        newArray[i] = callback(array[i]);
    }
    return newArray;
}

Если мы попробуем нашу функцию отправить массив в качестве первого параметра:

myMap([1, 2, 3], function(num){ return num * 3; });

вывод будет:

[3, 6, 9]

И если мы можем попробовать это с объектом:

myMap({one: 1, two: 2, three: 3}, 
      function(num, key){ return num * 3; });

вывод будет таким же:

[3, 6, 9]

Теперь вы можете попробовать написать остальные методы обработки коллекции аналогичным образом. Удачи!