Уменьшить, Фильтровать, Включает, Карта, ForEach

Одна из фундаментальных вещей, которые мы делаем в разработке внешнего интерфейса, — это извлечение данных из API, выполнение некоторых операций или проверка чего-либо в нем, а затем отображение их в пользовательском интерфейсе.

Эти данные обычно читаются как JSON или массив JSON. Вот некоторые из наиболее распространенных операций, которые мы пытаемся выполнить с этими данными:

  • Извлечение значений, удовлетворяющих определенным условиям, с помощью функции «Фильтр».
  • Вычисление значения в массиве с помощью функции Reduce.
  • Изменение, создание или сравнение объектов/значений путем перебора массива с помощью Map или ForEach.
  • Выполните некоторые операции с данными, чтобы получить необходимые результаты, которые должны отображаться в пользовательском интерфейсе.

Давайте рассмотрим пример, чтобы быстро понять, как правильно использовать эти функции Javascript. Допустим, мы пытаемся создать некую панель пользовательского интерфейса, показывающую данные о криптовалюте, которые мы получаем из общедоступных API-интерфейсов Coinbase. Ниже приведены реальные данные, с которыми вы можете иметь дело во многих различных случаях использования.

First API
Sample JSON response from Coinbase's currency API.
https://api.coinbase.com/v2/currencies
Note: This is just a sample. Actual response is much larger.
This API returns a list of currencies and their ids 
{
  "data": [
    {
      "id": "AED",
      "name": "United Arab Emirates Dirham",
      "min_size": "0.01000000"
    },
    {
      "id": "AFN",
      "name": "Afghan Afghani",
      "min_size": "0.01000000"
    },
    {
      "id": "ALL",
      "name": "Albanian Lek",
      "min_size": "0.01000000"
    },
    {
      "id": "AMD",
      "name": "Armenian Dram",
      "min_size": "0.01000000"
    },
  }
}

Вот еще один API, который дает обменный курс для соответствующего кода валюты с биткойнами.

Second API
Sample JSON response from Coinbase's exchange rate API
https://api.coinbase.com/v2/exchange-rates?currency=BTC
{
  "data": {
    "currency": "BTC",
    "rates": {
      "AED": "36.73",
      "AFN": "589.50",
      "ALL": "1258.82",
      "AMD": "4769.49",
      "ANG": "17.88",
      "AOA": "1102.76",
      "ARS": "90.37",
      "AUD": "12.93",
      "AWG": "17.93",
      "AZN": "10.48",
      "BAM": "17.38",
    }
  }
}

Что нам может понадобиться сделать с этими данными?

Использование фильтра и включения

Фильтр можно использовать всякий раз, когда вы хотите проверить, выполняется ли какое-либо условие для каждого элемента в массиве, и если да, поместить их в новый массив.

В нашем примере мы хотим получить объекты кода валюты списка предопределенных валют из всего списка, и вы хотите использовать только эти коды валют для отображения чего-либо.

These currencies could be configured elsewhere.
requiredCurrencies = ['US Dollar', 'Indian Rupee', 'Japanese Yen']

Теперь мы хотели бы отфильтровать коды валют из большого списка JSON (первый API), где валюта принадлежит нашему требуемому списку.

Here, we assume data is the array of JSONs we get in the API response object.
filteredData = data.filter((item) => requiredCurrencies.includes(item.name))
// Filtered data output
[
    {
        "id": "INR",
        "name": "Indian Rupee",
        "min_size": "0.01000000"
    },
    {
        "id": "JPY",
        "name": "Japanese Yen",
        "min_size": "1.00000000"
    },
    {
        "id": "USD",
        "name": "US Dollar",
        "min_size": "0.01000000"
    }
]

Обозначение со стрелкой — это удобный способ записи встроенных функций, подобных приведенной выше. Также обратите внимание на использование функции array.includes(). Он вернет true, если данный массив содержит значение, которое мы ему передаем.

В нашем случае, если имя валюты находится в требуемых валютах, функция фильтра добавит этот объект валюты в filteredData.

В качестве альтернативы, если вы хотите использовать оператор return в стрелочной нотации, вы можете использовать фигурные скобки.

filteredData2 = data.filter((item) => 
    {
        console.log('test');
        return requiredCurrencies.includes(item.name)
    });

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

Использование карты и ForEach

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

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

Предположим, что currencies — это массив JSON всех кодов валют, а rates — это массив JSON обменных курсов для соответствующих кодов валют (проверьте второй API). Мы можем получить наши пары значений меток следующим образом.

LabeledData = currencies.map((item) => {
    return {
        label: item['name'],
        value: rates[item.id]
        }
});

Итак, array.map выполняет функцию и возвращает значение для каждого элемента массива. Эти значения сохраняются в новом массиве. Вот как выглядит сопоставленный LabeledData (показаны только первые несколько элементов).

[
    {
        "label": "United Arab Emirates Dirham",
        "value": "3.673"
    },
    {
        "label": "Afghan Afghani",
        "value": "88.499983"
    },
    {
        "label": "Albanian Lek",
        "value": "111.05"
    },
    {
        "label": "Armenian Dram",
        "value": "488.092713"
    },
    {
        "label": "Netherlands Antillean Gulden",
        "value": "1.80142"
    },
    {
        "label": "Angolan Kwanza",
        "value": "450.646"
    },
    {
        "label": "Argentine Peso",
        "value": "110.698001"
    },
]

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

Использование уменьшения

Допустим, у нас есть портфель JSON, который состоит из всех криптовалют, принадлежащих пользователю. Мы хотим рассчитать и показать чистую стоимость их криптопортфеля в долларах США. Предположим, у вас есть обменный курс доллара США для каждой криптовалюты в этом JSON.

(Значения являются фиктивными значениями)

portfolio = [
    {
        "label": "BTC",
        "quantity": 3,
        "rate": 200,
    },
    {
        "label": "ETH",
        "quantity": 5,
        "rate": 100,
    },
    {
        "label": "LUNA",
        "quantity": 2,
        "rate": 50,
    },
    {
        "label": "SOL",
        "quantity": 10,
        "rate": 10,
    },
]

Простое наблюдение говорит нам об этом.

netWorth = sum(quantity * rate)
netWorth = 3*200 + 5*100 + 2*50 + 10*10 = $ 1300

Та же операция может быть выполнена с массивом с помощью функции reduce() следующим образом.

initial = 0; //Declare an initial value
netWorth = portfolio.reduce((netValue, item) => netValue + item.quantity*item.rate, initial);
// This computes to networth = 1300

Таким образом, вы можете вычислить одно значение в массиве. Функция также принимает начальное значение для начала.

Краткое содержание

  • array.filter((item) => some condition); используется для извлечения элементов из массива, соответствующих определенным условиям.
  • array.includes(value) возвращает True, если значение присутствует в данном массиве.
  • array.map((item) => some function); выполняет данную функцию для каждого элемента массива, и соответствующие результаты сохраняются в новом массиве.
  • array.forEach((item) => some function); делает то же самое, что и array.map, но изменяет существующий массив, а не создает новый.
  • array.reduce((value, item) => some function/operation, initialValue); выполняет заданную функцию для каждого элемента массива и передает возвращаемое значение следующей итерации. Таким образом, возвращаемое значение может быть доступно и обновлено на каждой итерации, что дает окончательное значение в конце цикла.