Array.prototype.reduce()
reduce()
方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。
reducer 函数接收4个参数:
- Accumulator (acc) (累计器)
- Current Value (cur) (当前值)
- Current Index (idx) (当前索引)
- Source Array (src) (源数组)
您的 reducer 函数的返回值分配给累计器,该返回值在数组的每个迭代中被记住,并最后成为最终的单个结果值。
callback
执行数组中每个值 (如果没有提供
initialValue则第一个值除外
)的函数,包含四个参数:
accumulator
累计器累计回调的返回值; 它是上一次调用回调时返回的累积值,或
initialValue
(见于下方)。
currentValue
数组中正在处理的元素。
index
可选数组中正在处理的当前元素的索引。 如果提供了
initialValue
,则起始索引号为0,否则从索引1起始。
array
可选调用
reduce()
的数组
initialValue
可选(reduce接收一个初始值)作为第一次调用
callback
函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错。
注意:
提供初始值通常更安全
由reduce
返回的值将是最后一次回调返回值,除了最后一次回调,每次回调的返回值,将作为下一次的accumulator
值 。
示例:
1、数组每项的和
var arr = [10, 20, 30, 40];
var sum = arr.reduce((acc, cur, index) => {
return acc + cur
}, 0)
console.log(sum)
2、二维数组转一维
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(
function(a, b) {
return a.concat(b);
},
[]
);
// flattened is [0, 1, 2, 3, 4, 5]
3、查找数组中元素的个数:
var obj = {};
var arr = ['a','b','a','c'];
var sum = arr.reduce((acc, cur, index) => {
acc.indexOf(cur) != -1 ? obj[cur]++ : obj[cur] = 1,acc.push(cur)
return acc;
}, [])
console.log(obj) //{a: 2, b: 1, c: 1}
4、示例,多个异步请求同步执行
Promise和async await的结合:
var setTime = function(v){
return new Promise(function(resolve, reject){
setTimeout(()=> {
console.log(v)
resolve();
}, 1000)
})
}
var arr = [10,20,30,40];
arr.reduce(async function(acc,cur,index){
return acc.then(() => {
//第二种实现方法
// return new Promise(async (resolve, reject) => {
// await setTime(cur);
// resolve();
// })
return (async function a(){
//await之前的宏任务,因为上一个异步的await完成后,就会立即执行该宏任务
//console.log(cur)
await setTime(cur);
//await之后的宏任务,该await执行完后,立即执行后面的宏任务,相当于对该await的补充
// console.log(cur)
})()
})
},Promise.resolve())
地址 :https://blog.csdn.net/zyz00000000/article/details/116136668
5、依次执行Promise对象——注意:最后一次回调的结果作为reduce方法的返回值
function runPromiseInSequence(arr, input) {
return arr.reduce(
(promiseChain, currentFunction) => promiseChain.then(currentFunction),
Promise.resolve(input)//第二个参数传入的值需要开启Promise
);
}
// promise function 1
function p1(a) {
return new Promise((resolve, reject) => {
resolve(a * 1);
});
}
// 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)
.then(console.log); // 10*1*2*3*4 = 240
6、通过reduce实现map方法——深入理解arr[100]如何创建empty空项、与Array.aplly()类数组转数组的区别(间隔项为undefined);深入理解call和apply的this指向;
var arr = ['a','b',,'c','d']
//如果需要兼容map的empty的话,需要结合item值和index值。
//因为empty进不去callback回调,用push结合item来构造数组的话,会跳过empty项
if(!Array.prototype.mapUsingReduce){
Array.prototype.mapUsingReduce = function(callback, thisArg){//接收两个参数
return this.reduce((acc, cur, index, originArr) => {
//通过arr[100]的形式,间隔的项都是空项
//如果通过Array.call()的形式,间隔的项将是undefined
acc[index] = callback(cur, index, originArr);
return acc;
},[])
}
}
var result = arr.mapUsingReduce(function(item, idx){
console.log(this)
return item;
}, 0)
console.log(result) //["a", "b", empty, "c", "d"]
过滤empty空项:
var arr = ['a','b',,'c','d']
if(!Array.prototype.mapUsingReduce){
Array.prototype.mapUsingReduce = function(callback, thisArg){//接收两个参数
return this.reduce((acc, cur, index, originArr) => {
console.log(index)
acc.push(callback.call(thisArg, cur, index, originArr)) //返回值length值
return acc;
},[])
}
}
var result = arr.mapUsingReduce(function(item, idx){
console.log(this)
return item;
}, 0)
console.log(result) //["a", "b", "c", "d"]
reduceRight方法
reduceRight()
方法接受一个函数作为累加器(accumulator)和数组的每个值(从右到左)将其减少为单个值。
MDN地址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce