Старая добрая доверенная структура данных, массив. Мы все знаем, что они из себя представляют, и, вероятно, используем их чаще, чем, я уверен, планировалось. Вы можете выполнять с ними множество операций и, что важно, можете объединять несколько методов (сопоставлять, фильтровать, уменьшать и т. д.), чтобы получить желаемый результат. Эта гибкость также может быть ахиллесовой пятой с точки зрения производительности…

Как мы теперь используем массивы?

Часто, когда мы обрабатываем данные, полезно разбить обработку на несколько независимых и составных этапов. Например, очень часто выбирают некоторые данные из большего набора, а затем обрабатывают эти данные (карта/фильтр).

У вас может возникнуть соблазн сделать что-то вроде этого:

// Define example 'input'
const input = [1,2,3,4,5]

// Define my operations
const addTwo = number => number + 2
const multiplyByTen = number => number * 10
const divideByThree = number => number / 3
const filterLessThanTen = number => number > 10
const filterLessThanOFourteen = number => number > 14

// Get output
const output  = input.map(addTwo)
                     .map(multiplyByTen)
                     .map(divideByThree)
                     .filter(filterLessThanTen)
                     .filter(filterLessThanOFourteen)

// Show output
console.log(output)

Проблема с вышеизложенным заключается в том, что для каждого map или filter, который вы выполняете, он возвращает совершенно новый массив каждый раз (на самом деле причина, по которой мы можем связать вышеприведенное таким образом) означает, что мы только что создали пять в приведенном выше коде.

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

Что мы можем сделать лучше?

Вместо того, чтобы цеплять подобные методы, мы можем использовать удобный пакет под названием compose-transducers, который вы можете установить с помощью команды ниже:

// Using yarn
yarn add compose-transducers
// Using NPM
npm install compose-transducers --save

Этот пакет исправляет это, объединяя функции map и filter в приведенном выше примере следующим образом:

.map()

.map(addTwo).map(multiplyByTen).map(divideByThree) в const applyMaps = (x) => divideByThree(multiplyByTen(addTwo(x)))

.фильтр()

.filter(filterLessThanTwo).filter(filterLessThanOne) в const applyFilters = (x) => [filterLessThanTen, filterLessThanOFourteen].every(fn => fn(x))

Это превратит вышеуказанное в:

// Get output
const output  = input.map(applyMaps).filter(applyFilters)

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

Вместо создания двух массивов transient каждый элемент будет проходить через applyMaps и applyFilters перед помещением в выходной массив. Ниже приведен пример пакета в действии:

// Import package
import { composeTransducer } from 'compose-transducers'

// Define example 'input'
const input = [1,2,3,4,5]
// Define my operations
const addTwo = number => number + 2
const multiplyByTen = number => number * 10
const divideByThree = number => number / 3
const filterLessThanTen = number => number > 10
const filterLessThanOFourteen = number => number > 14
// Build operation list
const operationList = [{
  type:'map',
  funcs: [addTwo, multiplyByTen, divideByThree]
}, {
  type: 'filter',
  funcs: [filterLessThanTen, filterLessThanOFourteen]
}]

// Build a transducer to use & reuse later
const composedTransducer = composeTransducer(operationList)

// Get the output
const output = composedTransducer(input)

// Show output
console.log(output)

По сути, мы берем вход (массив), выполняем над ним ВСЕ операции и помещаем результаты в новый массив!

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

Если у вас есть комментарии, напишите их ниже, спасибо за внимание!