В
первой части мы остановились на следующей спецификации: Трансдьюсер — это функция принимающая функцию
step
, и возвращающая новую функцию
step
.
step⁰ → step¹
Функция
step
, в свою очередь, принимает текущий результат и следующий элемент, и должна вернуть новый текущий результат. При этом тип данных текущего результата не уточняется.
result⁰, item → result¹
Чтобы получить новый текущий результат в функции
step¹
, нужно вызвать функцию
step⁰
, передав в нее старый текущий результат и новое значение, которое мы хотим добавить. Если мы не хотим добавлять значение, то просто возвращем старый результат. Если хотим добавить одно значение, то вызываем
step⁰
, и то что он вернет возвращаем как новый результат. Если хотим добавить несколько значений, то вызываем
step⁰
несколько раз по цепочке, это проще показать на примере реализации трансдьюсера
flatten:
function flatten() {
return function(step) {
return function(result, item) {
for (var i = 0; i < item.length; i++) {
result = step(result, item[i]);
}
return result;
}
}
}
var flattenT = flatten();
_.reduce([[1, 2], [], [3]], flattenT(append), []); // => [1, 2, 3]
Т.е. нужно вызывать
step
несколько раз, каждый раз сохраняя текущий результат в переменную, и передавая его при следующем вызове, а в конце вернуть уже окончательный.
В итоге получается, что при обработке каждого элемента, одна функция
step
, вызывает другую, а та следующую, и так до последней служебной функции
step
, которая уже сохраняет результат в коллекцию (
append
из первой части).
Итак, сейчас мы можем:
- Изменять элементы (прим. map)
- Пропускать элементы (прим. filter)
- Выдавать для одного элемента несколько новых (прим. flatten)