js中数组reduce方法的使用和实现 您所在的位置:网站首页 斗罗大陆绝世唐门第三季漫画播第十一集动画解说 js中数组reduce方法的使用和实现

js中数组reduce方法的使用和实现

2024-05-27 20:14| 来源: 网络整理| 查看: 265

js中数组reduce方法的使用和实现 reduce方法定义

reduce() 方法对数组中的每个元素执行一个传入的callback回调函数(升序执行,空值和已删除的除外),将其结果汇总为单个返回值。

reduce方法语法

arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])

reduce方法参数

callback 自己传入的为数组中每个值 (如果没有传入 initialValue则第一个值除外)执行的函数,包含四个参数: (1)accumulator 累计器累计回调的返回值; 它是上一次调用callback回调时返回的值,或初始化时initialValue的值(见于下方)。

(2)currentValue 数组中当前正在处理的元素。 (3)index 可选 数组中当前正在处理的当前元素的索引。 如果提供了initialValue,则起始索引号为0,否则从索引1起始。 (4)selfArray可选 调用reduce()的源数组自身。

initialValue可选 作为第一次调用 callback函数时的第一个参数的值。 如果没有传入初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错。

reduce方法返回值

函数累计处理的结果(可以是任意值,取决于自己需要什么)。

reduce方法详细描述

reduce为数组中的每一个元素依次执行callback函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:

1、accumulator 累计器 2、currentValue 当前值 3、currentIndex 当前值的索引 4、selfArray数组本身

回调函数第一次执行时,accumulator 和currentValue的取值有两种情况:如果调用reduce()时提供了initialValue,accumulator取值为initialValue,currentValue取数组中的第一个值;如果没有提供 initialValue,那么accumulator取数组中的第一个值,currentValue取数组中的第二个值。 特别注意:如果没有提供initialValue,reduce 会从索引1的地方开始执行 callback 方法,跳过第一个索引。如果提供initialValue,从索引0开始。

如果调用reduce函数的数组为空且没有提供initialValue,会抛出TypeError 。如果数组仅有一个元素(无论位置如何)并且没有提供initialValue, 或者有提供initialValue但是数组为空,那么此唯一值将被返回并且callback不会被执行。

reduce方法使用示例

参数累加

// 不传入initialValue参数 let arr1 = [1,3, , ,5] let newArr = arr1.reduce((acc, cur, index, selfArr) => { console.log({acc, cur, index}) return acc + cur }) console.log(newArr) // {acc: 1, cur: 3, index: 1} // {acc: 4, cur: 5, index: 4} // 9 // 传入initialValue参数 let newArr1 = arr1.reduce((acc, cur, index) => { console.log({acc, cur, index}) return acc + cur }, 0) console.log(newArr1) // {acc: 0, cur: 1, index: 0} // {acc: 1, cur: 3, index: 1} // {acc: 4, cur: 5, index: 4} // 9

上述代码的最终结果都是返回数组中每个元素相加的和,区别就是第一组代码没有传入initialValue 参数,第二组传入了initialValue 参数。 根据打印结果可以看出,第一组没有传入initialValue参数的代码从arr1数组中索引为1的元素开始执行callback函数,一共执行了两次,并且acc初始值为数组的第一个元素。第二组传入initialValue 参数的代码,从arr1原数组中索引值为0的元素开始执行并且acc初始值为传入的initialValue的值。两组代码都没有为arr1原数组中的空值执行callback函数。

数组对象结构的参数累加

let arr2 = [ { num: 1, }, { num: 5, }, { num: 7, } ] const newArr2 = arr2.reduce((acc, cur, index) => { return acc + cur.num }, 0) console.log(newArr2) // 13

上述代码是循环原数组arr2中每一项,并将每一项里面num的值进行相加,并且返回最后相加的结果。

数组去重 let arr3 = [1,2,1,1,3,5,2] const newArr3 = arr3.reduce((acc, cur) => { if (!acc.includes(cur)) acc.push(cur) return acc }, []) console.log(newArr3) // [1, 2, 3, 5]

上述代码 执行时初始参数传入一个空数组,然后开始从原数组arr3的第一个元素开始执行callback函数,每次都会利用数组的includes方法判断当前元素是否已经存在传入的数组里面,最后返回传入的数组赋值给acc参数。最后的结果就是已经去重好的新数组newArr3。

对象分类

let arr4 = [ { name: '小红', age: 21 }, { name: '小绿', age: 20 }, { name: '小蓝', age: 20 }, { name: '大白', age: 19 } ]; const newArr4 = arr4.reduce((acc, cur, index) => { if (!acc[cur.age]) acc[cur.age] = [] acc[cur.age].push(cur) return acc }, {}) console.log(newArr4) // { // 19: [{ name: '大白', age: 19 }], // 20: [{name: "小绿", age: 20}, {name: "小蓝", age: 20}], // 21: [{name: "小红", age: 21}] // }

上述代码将数据列表根据age进行分类,同样age的数据合并组成key:value形式展示出来。

计算数组中元素出现的次数

let arr5 = [1,2,3,1,2,1] const newArr5 = arr5.reduce((acc, cur) => { acc[cur]? acc[cur] ++: acc[cur] = 1 return acc }, {}) console.log(newArr5) // {1: 3, 2: 2, 3: 1}

上述代码利用对象中key – value数据形式来计算得出数组中每个元素出现的次数。最后在来看下空数组和数组只有一个参数时的值:

// 数组为空,传入initialValue初始值时和只有一个参数没有传入初始值时 console.log([].reduce((acc, cur) => { console.log(acc, cur) return cur }, 0)) // 0 console.log([1].reduce((acc, cur) => { console.log(acc, cur) return 10 })) // 1

下面根据上述描述和使用来模拟实现我们自己的reduce方法。

步骤思路

1、 将方法添加到Array的原型上 2、 传入回调函数形参和初始值形参 3、 判断initialValue 初始值是否传入 4、 判断原数组的元素是不是空值,来调用callback函数 5、 将每次执行的callback函数的返回值赋值给accumulator 6、 返回accumulator

实现代码 Array.prototype.myReduce = function(callback, initialValue) { let accumulator,initIndex, length = this.length // 判断initialValue初始参数有没有传入 if (initialValue || initialValue === 0) { // 空数组时直接返回传入的初始参数 if (length === 0) return initialValue initIndex = 0 accumulator = initialValue } else { // 空数组时报错 if (length === 0) throw new TypeError('xxxxxxxxx') // 原数组只有一个元素时,返回此元素 if (length === 1) return this[0] initIndex = 1 accumulator = this[0] } for (let index = initIndex; index < length; index++) { // 通过hasOwnProperty方法剔除空值,然后将传入的callback函数的值赋值给accumulator累计参数 if(this.hasOwnProperty(index)) accumulator = callback(accumulator, this[index], index, this) } return accumulator } 测试验证 Array.prototype.myReduce = function(callback, initialValue) { let accumulator,initIndex, length = this.length // 判断initialValue初始参数有没有传入 if (initialValue || initialValue === 0) { // 空数组时直接返回传入的初始参数 if (length === 0) return initialValue initIndex = 0 accumulator = initialValue } else { // 空数组时报错 if (length === 0) throw new TypeError('xxxxxxxxx') // 原数组只有一个元素时,返回此元素 if (length === 1) return this[0] initIndex = 1 accumulator = this[0] } for (let index = initIndex; index < length; index++) { // 通过hasOwnProperty方法剔除空值,然后将传入的callback函数的值赋值给accumulator累计参数 if(this.hasOwnProperty(index)) accumulator = callback(accumulator, this[index], index, this) } return accumulator } // 不传入initialValue参数 let arr1 = [1,3, , ,5] let newArr = arr1.myReduce((acc, cur, index, selfArr) => { console.log({acc, cur, index}) return acc + cur }) console.log(newArr) // {acc: 1, cur: 3, index: 1} // {acc: 4, cur: 5, index: 4} // 9 // 传入initialValue参数 let newArr1 = arr1.myReduce((acc, cur, index) => { console.log({acc, cur, index}) return acc + cur }, 0) console.log(newArr1) // {acc: 0, cur: 1, index: 0} // {acc: 1, cur: 3, index: 1} // {acc: 4, cur: 5, index: 4} // 9 let arr2 = [ { num: 1, }, { num: 5, }, { num: 7, } ] const newArr2 = arr2.myReduce((acc, cur, index) => { return acc + cur.num }, 0) console.log(newArr2) // 13 let arr3 = [1,2,1,1,3,5,2] const newArr3 = arr3.myReduce((acc, cur) => { if (!acc.includes(cur)) acc.push(cur) return acc }, []) console.log(newArr3) // [1, 2, 3, 5] let arr4 = [ { name: '小红', age: 21 }, { name: '小绿', age: 20 }, { name: '小蓝', age: 20 }, { name: '大白', age: 19 } ]; const newArr4 = arr4.myReduce((acc, cur, index) => { if (!acc[cur.age]) acc[cur.age] = [] acc[cur.age].push(cur) return acc }, {}) console.log(newArr4) // { // 19: [{ name: '大白', age: 19 }], // 20: [{name: "小绿", age: 20}, {name: "小蓝", age: 20}], // 21: [{name: "小红", age: 21}] // } let arr5 = [1,2,3,1,2,1] const newArr5 = arr5.myReduce((acc, cur) => { acc[cur]? acc[cur] ++: acc[cur] = 1 return acc }, {}) console.log(newArr5) // {1: 3, 2: 2, 3: 1} // 数组为空,传入initialValue初始值时和只有一个参数没有传入初始值时 console.log([].myReduce((acc, cur) => { console.log(acc, cur) return cur }, 0)) // 0 console.log([1].myReduce((acc, cur) => { console.log(acc, cur) return 10 })) // 1

使用自己模拟实现的方法打印结果和原方法一致。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有