reduce你真的会用吗
或许大家都知道reduce
,但相信一定会有一部分跟我一样只是知道却没怎么用过。不过没关系,看完本文,你会发现reduce
在特地场景有多香。
语法
arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
参数
callback
- 执行数组中每个值 (如果没有提供
initialValue则第一个值除外
)的函数,包含四个参数:
- 累计器累计回调的返回值; 它是上一次调用回调时返回的累积值,或
initialValue
(见于下方)。 currentValue
- 数组中正在处理的元素。
index
可选- 数组中正在处理的当前元素的索引。如果提供了
initialValue
,则起始索引号为0,否则从索引1起始。 array
可选- 调用
reduce()
的数组 accumulator
initialValue
「可选」
作为第一次调用 callback
函数时的第一个参数的值。如果没有提供初始值,则将使用数组中的第一个元素。在没有初始值的空数组上调用 reduce
将报错。
返回值
函数累计处理的结果
实例
数组求和
const arr = [1,2,3,4,5]; const result = arr.reduce(function (pre, cur, index, arr) { console.log('pre:' + pre, 'cur:' + cur, 'index:' + index) return pre + cur }); console.log(result); // pre:1 cur:2 index:1 // pre:3 cur:3 index:2 // pre:6 cur:4 index:3 // pre:10 cur:5 index:4 // 15
可以看到它是从数组的第二个元素还是执行的,第一轮pre
的值为数组的第一个元素 1 ,随后每次 加上当前数组位置的值再返回,从而实现累计的过程。
数组去重
const arr = [1,1,3,5,5,7,9]; // 给pre设置默认的空数组[] let arrByFilter = arr.reduce((pre, cur)=> pre.includes(cur) ? pre : pre.concat(cur),[]); console.log(arrByFilter); // [1, 3, 5, 7, 9]
查找字符串的公共前缀
const strArr = ["flower","flow","flight"] const prefix = strArr.reduce((pre, cur) => { while (!cur.startsWith(pre)) { pre = pre.substring(0, pre.length - 1); } return pre; }, strArr[0]); console.log(prefix); // fl
手写 reduce
Array.prototype.myReduce = function (callback, initialValue) { // 判断调用的是否是数组,以及传入的callback是否是函数 if (this == undefined) { throw new TypeError('this is null or not defined'); } if (typeof callback !== 'function') { throw new TypeError(callbackfn + ' is not a function'); } // 空数组也是不允许的 if (this.length == 0) { throw new TypeError('Reduce of empty array with no initial value'); } // 让O成为回调函数的对象传递(强制转换对象) const O = Object(this); // >>>0 保证len为number,且为正整数 const len = this.length >>> 0; // 保存初始值,初始值不传的时候为undefined let accumulator = initialValue; // 标志位 let k = 0; // 如果第二个参数为undefined的情况,则数组的第一个有效值作为累加器的初始值 if (accumulator === undefined) { // 这里是k++,就是赋值完成之后k再加1 accumulator = O[k++]; } // 此时如果有初始值,k是0,如果无初始值k是1 for (k; k < len; k++) { accumulator = callback.call(this, accumulator, O[k], k, O); } return accumulator; } console.log([2, 4, 6].myReduce((pre, cur) => pre + cur)); // 12 console.log([2, 4, 6].myReduce((pre, cur) => pre + cur, 10)); // 22
参考:
- Array.prototype.reduce() - JavaScript | MDN (mozilla.org)