reduce用法详解总结
- 1.reduce语法说明
- 1.1 方法介绍
- 1.2 参数说明
- 1.3 执行机制
- 1.4 简单示例:数组求和
- 2. 高级用法
- 2.1 权重求和
- 2.2 代替some和every
- 2.3 数组扁平
- 2.4 数组去重
- 2.5 字符统计和单词统计
- 2.6 数组成员特性分组
- 2.7 数字千分化
reduce函数是一个神奇的函数
1.reduce语法说明
1.1 方法介绍
reduce()
方法对数组中的每个元素执行一次提供的回调函数,且该函数为升序执行,并将其结果汇总为单个返回值。
1.2 参数说明
| let value = arr.reduce(function(accumulator, currentValue, currentIndex, array) { |
| |
| }, [initial]); |
复制
- 第一个参数:callback函数。该函数会遍历并应用于所有数组元素,并将其结果带到到下一个调用。此回调函数包含四个参数:
- accumulator
:累计器(必需)。是上一个函数调用的结果,第一次等于 initial(如果提供了 initial 的话)
- currentValue
:当前元素(必需)。数组中正在处理的元素。
- currentIndex
:当前处理元素的索引(可选)。如果提供了initialValue,则起始索引号为0,否则从索引1起始。
- array
:原始数组(可选)。 - 第二个参数:initialValue初始值(可选)
1.3 执行机制
reduce为数组中的每一个元素依次执行callback函数


值得注意的是:(如上图所示,回调函数第一次执行时)
- 如果没有提供
initialValue
:accumulator取数组中的第一个值,currentValue取数组中的第二个值。reduce 会从索引1的地方开始执行 callback 方法,跳过第一个索引。 - 如果提供了
initialValue
:accumulator取值为initialValue,currentValue取数组中的第一个值。reduce 会从从索引0开始执行 callback 方法。
1.4 简单示例:数组求和
| let arr = [1, 2, 3, 4, 5]; |
| let result = arr.reduce((sum, current) => sum + current, 0); |
| console.log(result); |
复制
传递给 reduce 的函数仅使用了 2 个参数,通常这就足够了。
- 在第一次运行时,sum 的值为初始值 initial(reduce 的最后一个参数),等于 0,current 是第一个数组元素,等于 1。所以函数运行的结果是 1。
- 在第二次运行时,sum = 1,我们将第二个数组元素(2)与其相加并返回。
- 在第三次运行中,sum = 3,我们继续把下一个元素与其相加,以此类推……
计算流程:

2. 高级用法
2.1 权重求和
| const scores = [ |
| { score: 90, subject: "chinese", weight: 0.5 }, |
| { score: 95, subject: "math", weight: 0.3 }, |
| { score: 85, subject: "english", weight: 0.2 } |
| ]; |
| const result = scores.reduce((acc, cur) => acc + cur.score * cur.weight, 0); |
| console.log(result); |
复制
2.2 代替some和every
| const scores = [ |
| { score: 45, subject: "chinese" }, |
| { score: 90, subject: "math" }, |
| { score: 60, subject: "english" } |
| ]; |
| |
| |
| const isAtLeastOneQualified = scores.reduce((acc, cur) => acc || cur.score >= 60, false); |
| |
| |
| const isAllQualified = scores.reduce((acc, cur) => acc && cur.score >= 60, true); |
复制
2.3 数组扁平
| const flatArr = (arr) => { |
| return arr.reduce((acc, cur) => acc.concat(Array.isArray(cur) ? flatArr(cur) : cur), []) |
| } |
| const arr = [0, 1, [2, 3], [4, 5, [6, 7]], [8, [9, 10, [11, 12]]]]; |
| console.log(flatArr(arr)); |
复制
2.4 数组去重
| const getUnique = (arr) => { |
| return arr.reduce((acc, cur) => acc.includes(cur) ? acc : [...acc, cur], []); |
| } |
| const arr = [2, 1, 0, 3, 2, 1, 2]; |
| console.log(getUnique(arr)); |
复制
2.5 字符统计和单词统计
| const str = "今天是个好日子呀,哈哈今天真开心呀!"; |
| const getCharCount = (arr=[]) => { |
| return arr.reduce((acc, cur) => (acc[cur] = (acc[cur] || 0) + 1, acc), {}); |
| } |
| let res = getCharCount(str.split('')); |
| console.log(res); |
| |
| '今': 2, |
| '天': 2, |
| '是': 1, |
| '个': 1, |
| '好': 1, |
| '日': 1, |
| '子': 1, |
| '呀': 2, |
| ',': 1, |
| '哈': 2, |
| '真': 1, |
| '开': 1, |
| '心': 1, |
| '!': 1 |
| } |
复制
注解:
逗号运算符总是返回最后一个值,比如 const a = (1,2,3); 的结果就是 a = 3,这里只是为了方便用了逗号运算符来完成acc[cur] = (acc[cur] || 0) + 1
这个操作,最后返回 acc。
此方法是字符统计和单词统计的原理,入参时把字符串处理成数组即可。
2.6 数组成员特性分组
| function Group(arr = [], key) { |
| return key ? arr.reduce((t, v) => (!t[v[key]] && (t[v[key]] = []), t[v[key]].push(v), t), {}) : {}; |
| } |
| |
| const arr = [ |
| { area: "GZ", name: "YZW", age: 27 }, |
| { area: "GZ", name: "TYJ", age: 25 }, |
| { area: "SZ", name: "AAA", age: 23 }, |
| { area: "FS", name: "BBB", age: 21 }, |
| { area: "SZ", name: "CCC", age: 19 } |
| ]; |
| Group(arr, "area"); |
| |
复制
2.7 数字千分化
| function ThousandNum(num = 0) { |
| const str = (+num).toString().split("."); |
| const int = nums => nums.split("").reverse().reduceRight((t, v, i) => t + (i % 3 ? v : `${v},`), "").replace(/^,|,$/g, ""); |
| const dec = nums => nums.split("").reduce((t, v, i) => t + ((i + 1) % 3 ? v : `${v},`), "").replace(/^,|,$/g, ""); |
| return str.length > 1 ? `${int(str[0])}.${dec(str[1])}` : int(str[0]); |
| } |
| |
| |
| ThousandNum(1234); |
| ThousandNum(1234.00); |
| ThousandNum(0.1234); |
| ThousandNum(1234.5678); |
复制
