Array.prototype.reduceRight() - JavaScript 编辑
reduceRight()
方法接受一个函数作为累加器(accumulator)和数组的每个值(从右到左)将其减少为单个值。
The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.
对于从左至右遍历的相似方法请参阅 Array.prototype.reduce()
.
语法
arr.reduceRight(callback(accumulator, currentValue[, index[, array]])[, initialValue])
参数
callback
- 一个回调函数,用于操作数组中的每个元素,它可接受四个参数:
accumulator
- 累加器:上一次调用回调函数时,回调函数返回的值。首次调用回调函数时,如果
initialValue
存在,累加器即为initialValue
,否则须为数组中的最后一个元素(详见下方initialValue
处相关说明)。 currentValue
- 当前元素:当前被处理的元素。
index
可选- 数组中当前被处理的元素的索引。
array
可选- 调用
reduceRight()
的数组。
initialValue
可选- 首次调用
callback
函数时,累加器accumulator
的值。如果未提供该初始值,则将使用数组中的最后一个元素,并跳过该元素。如果不给出初始值,则需保证数组不为空。
否则,在空数组上调用reduce
或reduceRight
且未提供初始值(例如[].reduce( (acc, cur, idx, arr) => {} )
)的话,会导致类型错误TypeError: reduce of empty array with no initial value
。 返回值
执行之后的返回值。
描述
reduceRight
为数组中每个元素调用一次 callback
回调函数,但是数组中被删除的索引或从未被赋值的索引会跳过。回调函数接受四个参数:初始值(或上次调用回调的返回值)、当前元素值、当前索引,以及调用迭代的当前数组。
可以像下面这样调用 reduceRight
的回调函数 callback
:
array.reduceRight(function(accumulator, currentValue, index, array) {
// ...
});
首次调用回调函数时,accumulator
和 currentValue
的可能取值情况有两种:
- 如果在调用
reduceRight
时提供了initialValue
参数,则accumulator
等于initialValue
,currentValue
等于数组中的最后一个元素。 - 如果没有提供
initialValue
参数,则accumulator
等于数组最后一个元素,currentValue
等于数组中倒数第二个元素。
如果数组为空,但提供了 initialValue
参数,或如果数组中只有一个元素,且没有提供 initialValue
参数,将会直接返回 initialValue
参数或数组中的那一个元素。这两种情况下,都不会调用 callback
函数。
如果数组为空,且没有提供 initialValue
参数,则会抛出一个 TypeError
错误。
最终,首次调用时的情况可汇总为此表:
数组内元素数量 | 是否提供 initialValue | 结果 |
---|---|---|
> 1 | 未提供 | accumulator 为数组中(下略)最后一个元素currentValue 为倒数第二个元素 |
提供 | accumulator 为 initialValue currentValue 为最后一个元素 | |
= 1 | 未提供 | 直接返回数组中的唯一一个元素 |
= 0 | 提供 | 直接返回 initialValue |
未提供 | 抛出 TypeError 错误 |
该函数的完整执行过程见下例:
[0, 1, 2, 3, 4].reduceRight(function(previousValue, currentValue, index, array) {
return previousValue + currentValue;
});
一共会调用四次回调函数,每次调用的参数及返回值如下:
callback | previousValue | currentValue | index | array | 返回值 |
---|---|---|---|---|---|
第一次调用 | 4 | 3 | 3 | [0,1,2,3,4] | 7 |
第二次调用 | 7 | 2 | 2 | [0,1,2,3,4] | 9 |
第三次调用 | 9 | 1 | 1 | [0,1,2,3,4] | 10 |
第四次调用 | 10 | 0 | 0 | [0,1,2,3,4] | 10 |
reduceRight
返回值是最后一次调用回调的返回值(10
)。
如果提供了一个 initialValue
参数,则结果如下:
[0, 1, 2, 3, 4].reduceRight(function(previousValue, currentValue, index, array) {
return previousValue + currentValue;
}, 10);
callback | previousValue | currentValue | index | array | 返回值 |
---|---|---|---|---|---|
第一次调用 | 10 | 4 | 4 | [0,1,2,3,4] | 14 |
第二次调用 | 14 | 3 | 3 | [0,1,2,3,4] | 17 |
第三次调用 | 17 | 2 | 2 | [0,1,2,3,4] | 19 |
第四次调用 | 19 | 1 | 1 | [0,1,2,3,4] | 20 |
第五次调用 | 20 | 0 | 0 | [0,1,2,3,4] | 20 |
这时,reduceRight
返回值为 20。
示例
求一个数组中所有值的和
var sum = [0, 1, 2, 3].reduceRight(function(a, b) {
return a + b;
});
// sum is 6
扁平化(flatten)一个二维数组
var flattened = [[0, 1], [2, 3], [4, 5]].reduceRight(function(a, b) {
return a.concat(b);
}, []);
// flattened is [4, 5, 2, 3, 0, 1]
运行一个带有回调每个函数将其结果传给下一个的异步函数列表
const waterfall = (...functions) => (callback, ...args) =>
functions.reduceRight(
(composition, fn) => (...results) => fn(composition, ...results),
callback
)(...args);
const randInt = max => Math.floor(Math.random() * max)
const add5 = (callback, x) => {
setTimeout(callback, randInt(1000), x + 5);
};
const mult3 = (callback, x) => {
setTimeout(callback, randInt(1000), x * 3);
};
const sub2 = (callback, x) => {
setTimeout(callback, randInt(1000), x - 2);
};
const split = (callback, x) => {
setTimeout(callback, randInt(1000), x, x);
};
const add = (callback, x, y) => {
setTimeout(callback, randInt(1000), x + y);
};
const div4 = (callback, x) => {
setTimeout(callback, randInt(1000), x / 4);
};
const computation = waterfall(add5, mult3, sub2, split, add, div4);
computation(console.log, 5) // -> 14
// same as:
const computation2 = (input, callback) => {
const f6 = x=> div4(callback, x);
const f5 = (x, y) => add(f6, x, y);
const f4 = x => split(f5, x);
const f3 = x => sub2(f4, x);
const f2 = x => mult3(f3, x);
add5(f2, input);
}
展示 reduce 与 reduceRight 之间的区别
var a = ['1', '2', '3', '4', '5'];
var left = a.reduce(function(prev, cur) { return prev + cur; });
var right = a.reduceRight(function(prev, cur) { return prev + cur; });
console.log(left); // "12345"
console.log(right); // "54321"
定义可组合函数
组合函数的概念简单,它只是简单地结合了多个函数。它是一个从右向左流动的函数,用上一个函数的输出调用每个函数。
/**
* Function Composition is way in which result of one function can
* be passed to another and so on.
*
* h(x) = f(g(x))
*
* Function execution happens right to left
*
* https://en.wikipedia.org/wiki/Function_composition
*/
const compose = (...args) => (value) => args.reduceRight((acc, fn) => fn(acc), value)
// Increament passed number
const inc = (n) => n + 1
// Doubles the passed value
const double = (n) => n * 2
// using composition function
console.log(compose(double, inc)(2)); // 6
// using composition function
console.log(compose(inc, double)(2)); // 5
兼容旧环境(Polyfill)
reduceRight
被添加到 ECMA-262 标准第 5 版,因此它在某些实现环境中可能不被支持。把下面的代码添加到脚本开头可以解决此问题,从而允许在那些没有原生支持 reduceRight
的实现环境中使用它。
// Production steps of ECMA-262, Edition 5, 15.4.4.22
// Reference: http://es5.github.io/#x15.4.4.22
if ('function' !== typeof Array.prototype.reduceRight) {
Array.prototype.reduceRight = function(callback /*, initialValue*/) {
'use strict';
if (null === this || 'undefined' === typeof this) {
throw new TypeError('Array.prototype.reduceRight called on null or undefined');
}
if ('function' !== typeof callback) {
throw new TypeError(callback + ' is not a function');
}
var t = Object(this), len = t.length >>> 0, k = len - 1, value;
if (arguments.length >= 2) {
value = arguments[1];
} else {
while (k >= 0 && !(k in t)) {
k--;
}
if (k < 0) {
throw new TypeError('reduceRight of empty array with no initial value');
}
value = t[k--];
}
for (; k >= 0; k--) {
if (k in t) {
value = callback(value, t[k], k, t);
}
}
return value;
};
}
规范
Specification | Status | Comment |
---|---|---|
ECMAScript 5.1 (ECMA-262) Array.prototype.reduceRight | Standard | Initial definition. Implemented in JavaScript 1.8 |
ECMAScript 2015 (6th Edition, ECMA-262) Array.prototype.reduceRight | Standard | |
ECMAScript (ECMA-262) Array.prototype.reduceRight | Living Standard |
浏览器兼容性
BCD tables only load in the browser
The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.相关链接
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论