reduce(Math.pow) 的使用
[3, 2, 1].reduce(Math.pow);
[3].reduce(Math.pow);
[].reduce(Math.pow, 3);
[].reduce(Math.pow);
大家知道以上三个表达式都会返回什么值吗?相信大家都会 Math.pow 和 reduce() 的使用有所了解,但是大家真的完全了解它们吗?
Math.pow(m, n) 接受两个参数,返回的结果是 m 的 n次幂。比如 Math.pow(3, 2) 返回的是 3 的二次方也就是9;
[].reduce((preValue, curValue, index, array) => {}, initValue)。接收两个参数,第一个参数是回调函数,接收四个参数。回调函数的第一个参数是上一次返回的结果,如过initValue 有值 preValue 就是首次就是 initValue 的值,curValue 是 arr[0] 的值,如果 initValue 没有值,那么 curValue 就是 arr[1] 的值,preValue 就是 arr[0] 的值。第三个参数 index 就是当前值的索引,array 就是调用的数组。
当 Math.pow 作为 reduce() 的参数的时候,reduce() 的 第一第二个参数,也就是 preValue 和 curValue 将会作为 Math.pow(m, n) 的第一第二个参数。
现在我们再来看一下上面四个表达式的结果:
[3, 2, 1].reduce(Math.pow);
// m -> 3 n -> 2 Math.pow(3, 2) -> 9
// 9
[3].reduce(Math.pow);
// 3
[].reduce(Math.pow, 3);
// 3
[].reduce(Math.pow);
// TypeError
看了上面的介绍,相信大家都对第一个结果没啥疑问了吧,但是后面的结果呢?
我们先看一下 MDN 上对于 reduce 的解释:
如果数组仅有一个元素(无论位置如何)并且没有提供初始值 initialValue,或者有提供 initialValue 但是数组为空,那么此唯一值将被返回且
callbackfn
不会被执行。
异常:TypeError
数组为空且初始值
initialValue
未提供。
再看一下 reduce() 的一些示例用法吧:
数组扁平化
let flattened = [[0, 1], [2, 3], [4, 5]].reduce(
(preValue, curValue) => preValue.concat(currentValue),
[]
)
// flattened is [0, 1, 2, 3, 4, 5]
数组去重
let myArray = ['a', 'b', 'a', 'b', 'c', 'e', 'e', 'c', 'd', 'd', 'd', 'd']
let myArrayWithNoDuplicates = myArray.reduce((preValue, curValue) => {
if(preValue.indexOf(curValue) === -1) {
preValue.push(curValue);
}
return preValue;
}, [])
按顺序运行 Promise
function runPromiseInSequence(arr, input) {
return arr.reduce((pre, cur) => {
pre.then(cur)
},Promise.resolve(input));
}
// promise function 1
function p1(a) {
return new Promise((resolve, reject) => {
resolve(a * 5)
})
}
// promise function 2
function p2(a) {
return new Promise((resolve, reject) => {
resolve(a * 2)
})
}
// function 3 - will be wrapped in a resolved promise by .then()
function f3(a) {
return a * 3
}
// promise function 4
function p4(a) {
return new Promise((resolve, reject) => {
resolve(a * 4)
})
}
const promiseArr = [p1, p2, f3, p4]
runPromiseInSequence(promiseArr, 10)
// 1200
使用函数组合实现管道
// Building-blocks to use for composition
const double = x => x + x
const triple = x => 3 * x
const quadruple = x => 4 * x
// Function composition enabling pipe functionality ps:这里使用了箭头函数实现柯里化
const pipe = (...functions) => initialValue => functions.reduce(
(acc, fn) => fn(acc),
initialValue
)
// Composed functions for multiplication of specific values
const multiply6 = pipe(double, triple)
const multiply9 = pipe(triple, triple)
const multiply16 = pipe(quadruple, quadruple)
const multiply24 = pipe(double, triple, quadruple)
// Usage
multiply6(6) // 36
multiply9(9) // 81
multiply16(16) // 256
multiply24(10) // 240
使用 reduce 实现 map
if (!Array.prototype.mapUsingReduce) {
Array.prototype.mapUsingReduce = function(callback, initialValue) {
return this.reduce(function(mappedArray, currentValue, currentIndex, array) {
mappedArray[currentIndex] = callback.call(initialValue, currentValue, currentIndex, array)
return mappedArray
}, [])
}
}
[1, 2, , 3].mapUsingReduce(
(currentValue, currentIndex, array) => currentValue + currentIndex + array.length
) // [5, 7, , 10]