JS数组之Reduce()用法

JS数组之Reduce()用法

一.语法

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

reduce()函数的参数有2个,第一个参数是一个函数(必须),第二个参数是一个初始值(非必须)。

callback:是一个回调函数,执行数组中每个值,注意:如果没有提供initialValue,将不会执行第一个值。包含4个参数:

  • accumulator 累计器累计回调的返回值,是上一次调用回调时返回的累计值,如果提供了initialValue,那么第一次执行时,为初始值initialValue
  • currentValue 当前数组中正在处理的元素
  • index 可选 数组中正在处理的当前元素的索引。如果提供了initialValue,则起始索引为0,如果没有提供,则起始索引为1
  • array 可选 原数组

initialValue: 初始值,本参数可选,作为第一次调用callback函数时的第一个参数的值。如果没有提供初始值,则将使用数组中的第一个元素。

PS:在没有初始值的空数组上调用Reduce函数会报错!

二.实例运用

1.数组里所有值求和
var arr = [1, 2, 3, 4, 5]
var result = arr.reduce(function (acc, cur, idx, src) {
  return acc + cur
},0)
console.log(result);//15

也可以写成箭头函数形式:

var result = arr.reduce((acc, cur) => acc + cur, 0)
console.log(result);//15
2.数组中对象的某一项所有值求和
var arr = [
  { classId: 1, score: 90 },
  { classId: 2, score: 80 },
  { classId: 3, score: 90 }
]
var result=arr.reduce((acc,cur)=>{
  return acc+cur.score
},0)
console.log(result);//260

注意,要累加对象数组中包含的值,必须要给初始值,便于能遍历到每个项,若不给初始值,结果会是字符串相加[object Object]8090

3.多维数组扁平化

一般比较复杂的数组或层级比较深的数组,需要进行递归运算,比较简单的数组稍微处理即可

简单数组(二位数组):

var arr = [[1, 2], [3, 4], [5, 6]]
var result = arr.reduce((acc, cur) => {
  return acc.concat(cur)
})
console.log(result);//[1, 2, 3, 4, 5, 6]

思路:处理简单的二维数组,是比较简单的,实际上就是拿第一个与后面的进行合并即可

层级比较深的数组:

var arr = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10];
    
function flat(array) {
  return array.reduce((acc, cur) => {
    return acc.concat(Array.isArray(cur) ? flat(cur) : cur)
  }, [])
}
var result=flat(arr)
console.log(result);//[1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12, 13, 14, 10]

思路:这是个嵌套层级比较深的多维数组,需要用到递归,也就是准备一个初始化的空数组,然后对数组中的每一项,进行判断,遇到数组,就重新调用外层的函数,层层递进,直到遇到非数组再合并,后面的执行过程也是一样,非数组,就直接合并,最后得出的结果是一个扁平化的数组

4.统计字符串中出现次数最多的字符
var str = "abccdefefdereerrddcbe"
var array = Array.from(str)
var arrayObj = array.reduce((acc, cur) => {
  if (cur in acc) {
    acc[cur]++
  } else {
    acc[cur] = 1
  }
  return acc
}, {})
console.log(arrayObj);//{a: 1, b: 2, c: 3, d: 4, e: 6, f: 2, r: 3}

var max = 0,name = "";
for (var i in arrayObj) {
  if (arrayObj[i] > max) {
    max = arrayObj[i]
    name = i
  }
}
console.log(name,max)//e 6

思路:先把字符串转为数组,因为reduce是数组方法,然后将reduce函数中的第二个参数初始化为一个对象,根据对象可以使用obj['xxx']这一特性,动态添加属性,判断某字符是否存在于对象中,如果不存在于对象中,初始值为1个,否则累加数量,最后输出值为一个包含各字符和统计数量的对象。

5.求数组中最大的值
var arr = [1, 2, 3, 4, 5]
var result = arr.reduce((acc, cur) => {
  return Math.max(acc, cur)
})
console.log(result);//5
6.数组去重
var arr = [1, 2, 3, 4, 5, 'liuqiao', 'xiaoming', 2, 4, 'liuqiao']
var result = arr.reduce((acc, cur) => {
  !acc.includes(cur) && acc.push(cur)
  return acc
}, [])
console.log(result);

三.总结

reduce()函数是数组的高级函数,有很多种用法,后面可以慢慢的拓展,另外,JavaScript还提供了reduceRight()这个函数,功能与reduce()相同,只不过reduceRight是从右往左进行运算,而reduce()是从左往右运算的