Парадигма программирования без стресса для фильтрации массивов и т. д.

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

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

Начнем с фильтрации массива домов с помощью цикла for.

class Home {
  constructor(
    public type: "Condo" | "House",
    public price: number,
  ) { }
}
const homes = [ 
  new Home("Condo", 100), 
  new Home("House", 200),
]

Фильтрация с помощью цикла For-Loop

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

function filterCondos(homes: Home[]): Home[] {
  const condos = []
  for (let i = 0; i < homes.length; ++i) {
    const home = homes[i]
    if (home.type === "Condo") {
      condos.push(home)
    }
  }
  return condos
}
const condos = filterCondos(homes)

Функция filterCondos просматривает и помещает дома в массив, где home.type === “Condo".

На базовом уровне мне не нравится filterCondos, потому что здесь много кода для простой задачи.

Проверяя тип, home.type === "Condo" - единственная важная строка кода. Так почему же filterCondos такой раздутый? Как уменьшить избыток?

Фильтрация с помощью Array.prototype.filter

Парадигма функционального программирования позволяет с первого взгляда читать и понимать код.

function byCondo(home: Home): boolean {
  return home.type === "Condo"
}
const condos = homes.filter(byCondo)

Функция byCondo проверяет, является ли дом кондоминиумом. При использовании с Array.prototype.filter мы получаем массив condos.

Результат такой же, как при использовании filterCondos без лишнего кода.

Фильтрация с помощью функций Карри

Я хочу фильтровать по любому типу, а не только по «кондоминиуму». Это возможно путем создания функции, в которую передается тип и возвращается новая функция.

const condos = homes.filter(byType("Condo"))
const houses = homes.filter(byType("House"))

Этот прием называется каррирование. Это похоже на матрешку, если куклы являются функциями - функция возвращает функцию.

function byType(type: "Condo" | "House") {
  return function (home: Home): boolean {
    return home.type === type
  }
}

Для простоты используйте библиотеку типа lodash для создания функций карри.

import _ from "lodash"
function filterByType(type: "Condo" | "House", home: Home) {
  return home.type === type
}
const byType = _.curry(filterByType)
const condos = homes.filter(byType("Condo"))
const houses = homes.filter(byType("House"))

Выражение _.curry(filterByType) строит функцию byType.

Заключение

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

Есть и другие причины для использования функционального программирования, которые не обсуждались выше. Ознакомьтесь с дополнительными ресурсами ниже, чтобы получить более полное представление о функциональном программировании.

  1. Array Object API в сети разработчиков Mozilla (MDN)
  2. Краткая статья о цепочке Сумита Кумара Прадхана
  3. Длинная статья о цепочке от Этьена Талбота
  4. Плейлист функционального программирования FunFunFunction
  5. Почему так важно функциональное программирование от Навнит Сингх
  6. Функциональное программирование на C # Карлос Шульц.