TL; DR В этом сеансе мы изучим основы отображения, фильтрации и сокращения служебных функций в Javascript путем их реализации. Ура!

В наших примерах мы будем использовать функции _.map, _.filter и _.reduce из Lodash . Мы увидим, что они делают, как используются, и напишем нашу собственную реализацию на ванильном JS-коде.

Итак, приступим!

Функция карты

Я хотел бы представить функцию в виде черного ящика, который принимает входные данные, обрабатывает их, а затем выводит выходные данные. Применим это определение к каждой из функций, начинающихся с _.map

Из документации Lodash объявление функции _.map можно упростить до следующего

INPUTS:
collection (Array or Object)
callback function (with 3 arguments: value, index, collection)
OUTPUTS:
An array with values transformed by the callback. The size of this array always equals size of the collection passed as input.
PROCESS:
Invoke the callback function as we loop through each item in collection. The function will "transform" each item in collection.
_.map(collection, function)

Теперь, когда мы понимаем ввод, вывод и процесс, мы могли бы реализовать это самостоятельно, верно?

Прежде чем приступить к реализации, давайте посмотрим, как используется _.map и почему он используется.

Допустим, мы хотим взять список чисел и вернуть их квадраты. В нашем примере ниже мы передаем входные данные [2, 3, 5] и получаем результаты в виде их квадратов [4, 9, 25].

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

Теперь, когда мы понимаем, почему и что за функция, давайте рассмотрим «как», написав нашу собственную реализацию _.map. Вы готовы?

Пошагово:

  1. Инициализируйте переменную «_», а затем добавьте к ней свойство «карта».
  2. Мы будем использовать выражение функции и назначить его map. Эта функция будет принимать в качестве входных данных коллекцию и обратный вызов (мы это уже знаем!)
  3. Для каждого элемента в коллекции вызовите обратный вызов и передайте элемент в обратный вызов. Вставьте возвращаемое значение из обратного вызова в массив результатов.
  4. Вернуть массив результатов. И готово!

Примечание. Коллекция может быть либо массивом, либо объектом, поэтому реализация должна учитывать эти мелкие детали. Поэтому я использовал Array.isArray () для реализации немного другого способа обхода коллекции.

Вот как вы вызываете _.map с помощью объекта.

Теперь, когда мы узнали, как распотрошить функцию _.map и реализовать ее внутренности, давайте применим ту же методологию к функциям ._filter и _.reduce.

Функция фильтра

Из документации Lodash объявление функции _.filter можно упростить до следующего

INPUTS:
collection (Array or Object)
callback function (with 3 arguments: value, index, collection)
OUTPUTS:
An array with values filtered by the callback. 
Size of this array <= the size of the collection passed as input.
PROCESS:
Invoke the callback function as we loop through each item in collection. The function will apply a condition on each item and return a boolean. Only items that satisfy this condition will be returned in the output array.
_.filter(collection, function)

Вы понимали, насколько объявление устрашающе похоже на карту? :) Не волнуйтесь, мы рассмотрим различия между картой, фильтром и сокращением в резюме внизу сообщения!

Допустим, у нас есть массив чисел, и мы хотим извлечь только четные числа. В нашем примере ниже мы передаем входные данные [2, 3, 4, 5, 6, 8], и результаты будут иметь четные числа [2, 4, 6, 8]

Потрясающие! Теперь давайте посмотрим, как реализовать шаг за шагом (см. Встроенные комментарии)

И чтобы увидеть, как _.filter можно вызвать с вводом объекта

Далее идет могущественное _.reduce. Помните, могущественный, но не невозможный :) Внимание, так как будет немного сложнее обернуть голову, особенно если вы впервые видите его кишки!

Функция уменьшения

Из документации Lodash объявление функции _.reduce можно упростить до следующего

INPUTS:
collection (Array or Object)
callback function (with 3 arguments: value, index, collection)
accumulator (an initial value)
OUTPUTS:
An array with one single value returned by the callback.
This is always a single value!
PROCESS:
Invoke the callback function as we loop through each item in collection. The function will "reduce" or "accumulate" each item in collection.
_.reduce(collection, function, accumulator)

Допустим, у нас есть массив чисел, и мы хотим его подвести. В нашем примере ниже мы имеем в качестве входных данных [1, 2, 3] и возвращаем сумму 16 в качестве выходных данных. Почему 16? Потому что мы передаем в наш аккумулятор начальное значение 10! Обманывал тебя! Ну, не совсем, я просто хочу показать, что ваш аккумулятор не обязательно должен быть пустым, он может нести начальное значение.

Итак, вы готовы реализовать это со мной или как ?!

Обратите внимание, что произошло в коде иначе, чем _.map и _.filter. Поскольку функция аккумулятора - продолжать «накапливать», для каждого элемента в коллекции мы передаем текущее значение аккумулятора и сохраняем обновленный аккумулятор после вызова обратного вызова. Именно здесь многие из нас (включая меня!) Ошибаются. Как бы то ни было, мы победили сильных, не так ли?)

Наконец, для полноты, вот как вы вызываете функцию _.reduce с вводом Object.

Это был слегка надуманный пример, взятый непосредственно из документа Lodash, но, пожалуйста, найдите время, чтобы прочитать и понять, что означает эта строка:

(result[value] || (result[value] = [])).push(key);

На этом мы закончили!

Подведем итоги тому, что мы узнали сегодня

  1. Функции map, filter, reduce такие же, как и любые другие функции. Думайте о них как о черном ящике, принимающем входные данные, обрабатывающем эти входные данные и производящем выходные данные.
  2. Используйте карту, чтобы преобразовать коллекцию, фильтруйте, чтобы отфильтровать коллекцию, и уменьшить, чтобы уменьшить коллекцию до одного значения.
  3. map и filter почти такие же, за исключением того, что (1) map возвращает выходной массив точно такого же размера, что и входной массив, тогда как filter может возвращать любой размер от 0 до размера входного массива (2) обратный вызов карты преобразует значения по сравнению с возвратом обратного вызова фильтра только значения, удовлетворяющие условию.
  4. reduce может показаться немного сложным, но только из-за «аккумулятора».

Ресурсы

Курс Бьянки Гондалфо Основы JS для Functional V2 невероятно полезен!

Ура до следующего раза!