数组中关于reduce的常见总结

198 阅读2分钟
  • reduce【函数累计处理的结果】

    • 1、api:arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])

      • callback
      • initialValue可选
        • 作为第一次调用 callback函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错
    • 2、特别重要的几点

      • 空数组执行reduce会报错

      • 数组长度时1,且没有提供reduce初始值,这时reduce的回调函数是不会执行的,直接返回数组的第一项

           /*** 这里回调里面的console.log是不会执行的,只是输出了{x: 2} ***/
           [{ x: 2 }].reduce((a,b) => {
                console.log(a,b,"222",a.x, b.x)
                return Math.max( a.x, b.x )
           }); 
        
        
      • 关于第一次执行:

        • 回调函数第一次执行时,accumulator 和currentValue的取值有两种情况:如果调用reduce()时提供了initialValue,accumulator取值为initialValue,currentValue取数组中的第一个值;如果没有提供 initialValue,那么accumulator取数组中的第一个值,currentValue取数组中的第二个值。
      • 提供初始值通常更安全

            // reduce() 没有初始值
            [ { x: 2 }, { x: 22 }, { x: 42 } ].reduce( (a,b) => Math.max( a.x, b.x ) ); // NaN
            [ { x: 2 }, { x: 22 }            ].reduce( (a,b) => Math.max( a.x, b.x ) ); // 22
            [ { x: 2 }                       ].reduce( (a,b) => Math.max( a.x, b.x ) ); // { x: 2 }
            [                                ].reduce( (a,b) => Math.max( a.x, b.x ) ); // TypeError
        
    • 3、常见应用场景

      • 1、求和,求乘积
          var  arr = [1, 2, 3, 4];
          var sum = arr.reduce((x,y)=>x+y)//10
          var mul = arr.reduce((x,y)=>x*y)//24
      
      • 2、求对象里的属性求和
          var result = [        {            subject: 'math',            score: 10        },        {            subject: 'chinese',            score: 20        },        {            subject: 'english',            score: 30        }    ];
      
          var sum = result.reduce((a, b)=> a + b.score, 0));//60
      
      • 3、数组去重
          let arr = [1,2,3,4,4,1]
          let newArr = arr.reduce((a,b)=>{
              if(!a.includes(b)){
                return a.concat(b)
              }else{
                return b
              }
          },[])//[1,2,3,4]
      
      • 4、拉平数组
          let arr = [[0, 1], [2, 3], [4, 5]]
          let newArr = arr.reduce((a,b)=>{
              return a.concat(b)
          },[])//[0,1,2,3,4,5]
      
      • 5、拉平多维数组
          let arr = [[0, 1], [2, 3], [4,[5,6,7]]]
          const newArr = function(arr){
             return arr.reduce((a,b)=>a.concat(Array.isArray(b)?newArr(b):b),[])
          }
          newArr(arr)//[0,1,2,3,4,5,6,7]
      
      • 6、计算数组中每个元素出现的次数
          let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
          let nameNum = names.reduce((pre,cur)=>{
            if(cur in pre){
              pre[cur]++
            }else{
              pre[cur] = 1 
            }
            return pre
          },{}) // {'Alice':2,'Bob':1,'Tiff':1,'Bruce':1}
      

      • Tips拓展:

        • 1、reduceRight和reduce类似,只是方向不同

          • ECMAScript为数组提供了两个归并方法:reduce()和reduceRight()。这两个方法都会迭代数组的所有项,并在此基础上构建一个最终返回值。reduce()方法从数组第一项开始遍历到最后一项。而reduceRight()从最后一项开始遍历至第一项。