reduce
Это прабабушка для for, foreach, while и прочих подобных структур. Эта функция также известна под именем fold.
Опять начнем с примитивного примера.
var totalLength = 0;
for(var i=0; i< buffers.length; i++){
total.Length += buffers[i].length;
}
Просто суммируем длину буферов.
Какие шаги мы должны выполнить?
- Получить длины буферов
- Просуммировать длины
Use the function, Luke.
Сначала мы используем map, чтобы получить список, содержащий длины буферов
var totalLength = buffers.
map(function (buffer) {return buffer.length; })
А на втором шаге мы применим reduce, чтобы получить их сумму.
var totalLength = buffers.
map(function (buffer) {return buffer.length; }).
reduce(function(sum, curr){return sum+curr;}, 0);
[10, 5, 15, 10, 10].reduce(function(sum, curr){return sum+curr;}, 0);
// [10, 5, 15, 10, 10]
// sum curr
// => 0, 10 => 10
// => 10, 5 => 15
// => 15, 15 => 30
// => 30, 10 => 40
// => 40, 10 => 50
Но у нас уже было что-то похожее. Сравните.
function (prev, curr){return prev + curr;}
и
function add(a,b){
return a+b;
}
Поэтому мы можем немного упростить нашу функцию по вычислению суммарной длины буферов.
var totalLength = buffers.
map(function (buffer) {return buffer.length; }).
reduce(add, 0);
Теперь стало яснее? reduce просто суммирует все элементы списка, применяя функцию add. Начальное значение суммы равно нулю. Что может быть проще?
Но на этом упрощения не заканчиваются. Сравните
function (buffer) {return buffer.length; }
и
prop("length")
Брюки превращаются…
var totalLength = buffers.
map(prop("length")).
reduce(add, 0);
В элегантные шорты.
Ну и, естественно, мы можем записать это в одну строку
var totalLength = buffers.map(prop("length")).reduce(add, 0);
Использование свертки (reduce) вместо циклов позволяет нам думать на другом уровне абстракции. Мы совершаем операции над списком, а не на уровне каждого элемента.
var totalLength = 0;
for(var i=0; i< buffers.length; i++){
total.Length += buffers[i].length;
}
var totalLength = buffers.
map(function (buffer) {return buffer.length; })
var totalLength = buffers.
map(function (buffer) {return buffer.length; }).
reduce(function(sum, curr){return sum+curr;}, 0);
[10, 5, 15, 10, 10].reduce(function(sum, curr){return sum+curr;}, 0);
// [10, 5, 15, 10, 10]
// sum curr
// => 0, 10 => 10
// => 10, 5 => 15
// => 15, 15 => 30
// => 30, 10 => 40
// => 40, 10 => 50
function (prev, curr){return prev + curr;}
function add(a,b){
return a+b;
}
var totalLength = buffers.
map(function (buffer) {return buffer.length; }).
reduce(add, 0);
function (buffer) {return buffer.length; }
prop("length")
var totalLength = buffers.
map(prop("length")).
reduce(add, 0);
var totalLength = buffers.map(prop("length")).reduce(add, 0);