Если вы начинаете с функционального программирования и не знаете, что делать после map и filter, переходите к reduce.

Reduce - это святой Грааль универсальности, когда дело касается обработки объектов и списков. Его свойства позволяют реализовать практически все:
- вы можете определить свою начальную стоимость
- вы управляете типом вывода
- проходит через все элементы
Это означает, что вы всегда можете контролировать, что входит внутрь, что выходит наружу и что находится внутри. Имея это в виду, вы можете выполнять любую чистую операцию, какую захотите, во время итерации, поскольку она по-прежнему вы контролируете вывод. Например, вот как реализовать filter с помощью reduce:
// JS const filter = (fn, list) => list.reduce((acc, next) => (fn(next) ? acc.concat(next) : acc), []); // Haskell filter’ :: (a -> Bool) -> [a] -> [a] filter’ fn = foldr (\x xs -> if fn x then x:xs else xs) []
То же самое можно сделать и для map:
// JS const map = (fn, list) => list.reduce((acc, next) => acc.concat(fn(next)), []); // Haskell map’ :: (a -> b) -> [a] -> [b] map’ fn = foldr (\x xs -> fn x : xs) []
Имейте в виду, что reduce может создавать любой тип значения, поэтому вы можете выполнять итерации, требующие запоминания некоторого промежуточного значения. Например, если мы хотим выбрать строки, помещенные между двумя другими строками, у нас может быть объект {output: «», inbetween: false}. Потом:
- если
inbetween, а не конечная строка, объединить сoutput - если
inbetweenи конечная строка, вернутьoutputи установитьinbetweenна ложь - если не
inbetweenи начальная строка, установите дляinbetweenзначение true - если не
inbetweenи не начальная строка, просто верните аккумулятор
Просто возьмите свойство output, когда закончите, и все готово.
Так что в следующий раз, когда вы захотите использовать цикл for, используйте вместо него reduce! Если, конечно, это предпочтительный способ на вашем языке.