Рубрики
Без рубрики

Функциональное программирование с JavaScript ES6

Функциональное программирование с JavaScript ES6

Автор оригинала: Ajinkyax.

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

Оригинальный пост @ https://ajinkya.js.org/2018/05/02/functional-programming-es6-Cheatsheet.html.

Функции стрелки (Стрелки жира)

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

Пример

  const multiply = function(x,y) {
    return x * y;
  }
  // Can be rewritten as:
  const multiply = (x, y) => { return x * y };
  // Since the function is a single expression return and braces are not needed.
  const multiply = (x, y) => x * y;
  console.log(multiply(5,10)) //50

Читайте больше в mdn arrow_functions

Функция делегатов

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

Пример

const isZero = n => n === 0;
const a = [0,1,0,3,4,0];
console.log(a.filter(isZero).length); // 3

Выражения вместо утверждений

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

Отчет (плохо)

const getSalutation = function(hour) {
 var salutation; // temp value
 if (hour < 12) {
 	salutation = "Good Morning";
 }
 else {
 	salutation = "Good Afternoon"
 }
 	return salutation; // mutated value
 }
 

выражение (хорошо)

const getSalutation = (hour) => hour < 12 ? "Good Morning" : "Good Afternoon";
console.log(getSalutation(10)); // Good Morning

Функции высшего порядка

Функция, которая принимает другую функцию в качестве параметра или возвращает другую функцию.

Пример

function mapConsecutive(values, fn) {
 let result = [];
 for(let i=0; i < values.length -1; i++) {
 	result.push(fn(values[i], values[i+1]));
 }
 return result;
}

const letters = ['a','b','c','d','e','f','g'];

let twoByTwo = mapConsecutive(letters, (x,y) => [x,y]);
console.log(twoByTwo);
// [[a,b], [b,c], [c,d], [d,e], [e,f], [f,g]]

Карри

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

Пример

const convertUnits = (toUnit, factor, offset = 0) => 
  input => ((offset + input) * factor).toFixed(2).concat(toUnit);

const milesToKm = convertUnits('km', 1.60936, 0);
const poundsToKg = convertUnits('kg', 0.45460, 0);
const farenheitToCelsius = convertUnits('degrees C', 0.5556, -32);

milesToKm(10); //"16.09 km"
poundsToKg(2.5); //"1.14 kg"
farenheitToCelsius(98); //"36.67 degrees C"
const weightsInPounds = [5,15.4,9.8, 110];

// without currying
const weightsInKg = weightsInPounds.map(x => convertUnits('kg', 0.45460,
0)(x));
// with currying
const weightsInKg = weightsInPounds.map(poundsToKg);
// 2.27kg, 7.00kg, 4.46kg, 50.01kg

Функции манипуляции массива

Функции массива – это шлюз к функциональному программированию в JavaScript. Эти функции делают краткую работу наиболее необходимых процедур программирования, которые работают над массивами и коллекциями.

[]. Every (Fn) Проверяет, если все элементы в массиве проходят тест.

[] .some (fn) | [] .inCludes (Fn) Проверяет, проходит ли какие-либо элементы в массиве теста.

[] .find (fn) Возвращает значение первого элемента в массиве, который передает тест.

[] .Filter (FN) Создает массив, заполненный только элементами массива, которые проходят тест.

[] .map (fn) Создает новый массив с результатами функции, приложенной к каждому элементу в массиве.

[]. Резюка (FN (аккумулятор, CurrentValue)) Выполняет предоставленную функцию для каждого значения массива (из левой справа). Возвращает одно значение, аккумулятор.

[] .sort (fn (a, b)) Предупреждение, мутатирует состояние! Изменяет массив, сортируя элементы в массиве. Дополнительное сравнение функции может быть использовано для настройки сортировки поведение.

[... ARR] .sort () Используйте оператор распространения, чтобы избежать мутации.

[] .Reverse () Предупреждение, мутатирует состояние! Переворачивает порядок элементов в массиве. Используйте оператор распространения, чтобы избежать мутации. [... ARR] .Reverse ()

Несколько полезных библиотек для манипуляций данных:

Способ цепочки

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

Пример

let cart = [
  {name: "Drink", price: 3.12},
  {name: "Steak", price: 45.15},
  {name: "Drink", price: 11.01}
];

let drinkTotal = cart.filter(x=> x.name === "Drink")
 .map(x=> x.price)
 .reduce((t,v) => t +=v)
 .toFixed(2);

console.log(Total Drink Cost $${drinkTotal}); // Total Drink Cost $14.13

Трубопроводы

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

Пример

const pipe = functions => data => {
  return functions.reduce( (value, func) => func(value), data);
};

let cart = [3.12, 45.15, 11.01];
const addSalesTax = (total, taxRate) => (total * taxRate) + total;

const tally = orders => pipe([
 x => x.reduce((total, val) => total + val), // sum the order
 x => addSalesTax(x, 0.09),
 x => `Order Total = ${x.toFixed(2)}` // convert to text
])(orders);
// Order Total = 64.62