ES6的filter、map、reduce

提出问题

现在有一个需求:给一个数字数组,我们要对其进行一些操作
首先,将所有小于60的数取出来,然后将这些数都乘以2,最后将乘以2后的数全部加起来,最后打印加起来的值
其实这个需求挺简单的,无非就是几个循环,创建几个新数组保存一下,然后进行累加打印就行了。
好,既然提出了解决方法,那么直接撸代码

let arr = [30, 50, 142, 305, 20, 16, 66, 77, 88]
let arr1 = []
let arr2 = []
let sum = 0
// 这个循环把所有小于60的数放进了arr1数组
for (let i = 0; i < arr.length; i++) {
  if (arr[i] <= 60) {
    arr1.push(arr[i])
  }
}
console.log(arr1)
// 这个循环把arr1数组的所有数全部乘以2并放进arr2数组
for (let i = 0; i < arr1.length; i++) {
  arr2.push(arr1[i] * 2)
}
console.log(arr2)
// 这里一个循环求总和
for (let i = 0; i < arr2.length; i++) {
  sum += arr2[i]
}
console.log(sum)

在这里插入图片描述

提出优化

看!需求完成了
但有人突然提出:“我可以使用for of对其进行优化!”
那就满足一下他,上代码

 // 刚刚全部使用的for循环,有人提出,可以使用for of进行优化,确实,让我们来看看
    let arr = [30, 50, 142, 305, 20, 16, 66, 77, 88]
    let arr1 = []
    let arr2 = []
    let sum = 0
    // 这个循环把所有小于60的数放进了arr1数组
    for (let i of arr) {
      if (i <= 60) {
        arr1.push(i)
      }
    }
    console.log(arr1)
    // 这个循环把arr1数组的所有数全部乘以2并放进arr2数组
    for (let i of arr1) {
      arr2.push(i * 2)
    }
    console.log(arr2)
    // 这里一个循环求总和
    for (let i of arr2) {
      sum += i
    }
    console.log(sum)
    // 其实没多大变化

在这里插入图片描述

进一步优化

然而,for…of方法的优化效果好像不尽人意,同样还是三个循环和创建两个新数组,只是稍微减少了arr1[i]这类的操作

这时候 ES6说话了:“用我新增的数组方法它不香吗?”
好家伙,既然你这么说了,那就用你了

 // 这里我们就可以使用es6新增的数组方法,我们先看看他有多神奇
 // 也可以看看函数式编程是有多爽
    let arr = [30, 50, 142, 305, 20, 16, 66, 77, 88]
    let sum = arr.filter(function (n) {
      return n <= 60
    }).map(function (n) {
      return n * 2
    }).reduce(function (pervValue, n) {
      return pervValue + n
    })
    console.log(sum)
    // 这样就打印出了正确答案,先不急,我会一步一步来介绍这些数组方法

在这里插入图片描述
在使用了ES6的filter、map、reduce后,我们得到了正确结果的同时还减少了创建新数组的操作,
但这三个方法都是什么呢?让我一一介绍

filter()

filter 过滤器的意思,功能也跟过滤器一样
参数:filter 接收一个函数,function(currentValue,index,arr)
其函数接收三个参数:
currentValue 必须。当前元素的值
index 可选。当前元素的索引值
arr 可选。当前元素属于的数组对象
返回值:返回一个新数组,也就是在参数的函数中返回true的数
let arr = [30, 50, 142, 305, 20, 16, 66, 77, 88]

// 第一个参数必选,当前的值
// 第二个参数可选 当前元素索引值
// 第三个参数可选 当前元素属于的数组对象
let arr1 = arr.filter(function (currentValue, index, arr) {
  return currentValue <= 60 //我们只需要第一个参数,进行判断,filter会将内部函数返回为true的值作为返回值给一个新数组
})
console.log(arr1)

在这里插入图片描述

map()

map方法
参数:map 接收一个参数 function(currentValue,index,arr)
函数的接收三个参数:
currentValue 必须。当前元素的值
index 可选。当前元素的索引值
arr可选。当前元素属于的数组对象
返回值:返回一个新数组,也就是在参数的函数中进行操作过后的值

 let arr = [30, 50, 142, 305, 20, 16, 66, 77, 88]
    // 第一个参数必选,当前的值
    // 第二个参数可选 当前元素索引值
    // 第三个参数可选 当前元素属于的数组对象
    let arr1 = arr.map(function (currentValue, index, arr) {
      return currentValue * 2 //同样,我们只需要第一个参数,map会将经过内部函数操作后的值作为返回值给一个新数组,这里就是把arr中所有值乘以2给arr1
    })
    console.log(arr1)

在这里插入图片描述

reduce()

reduce 最复杂的方法
参数:filter接收两个参数
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
第一个参数:是一个函数
第二个参数:initalValue 就是最开始初始值
其函数接收四个参数:
total 必需。初始值, 或者计算结束后的返回值。
currentValue 必需。当前元素
currentIndex 可选。当前元素的索引
arr 可选。当前元素所属的数组对象。
reduce通常用来完成对数组值进行同一种操作的时候,就像现在的累加

 let arr = [30, 50, 142, 305, 20, 16, 66, 77, 88]
    // 第一个参数 必选 每次累加得到的值 也就是这次的total 是上次的total+currentValue的和
    // 第二个参数 必选 当前元素的值
    // 第三个参数 可选 当前元素的索引
    // 第四个参数 可选 当前元素所属的数组对象
    let sum = arr.reduce(function (total, currentValue, currentIndex, arr) {
      return total + currentValue //这里我们只用到了第一和第二个参数完成累加, 注意:第一次累加用的是initalValue 作为total
    }, 0)
    console.log(sum)

在这里插入图片描述
这里可能很难看懂,来分析几次累加就好了:

第一次 total +currentValue时,这里的total其实就是reduce的第二个参数initalValue,这里initalValue为0,也就是0加上currentValue,这时候currentValue的值为30, 所以第一次total + currentValue为30,那么下一次的total就成了30。
————————————————————————————————————————————————
第二次 total +currentValue时,这里的total是上一次total + currentValue的值:30,所以这次是30 +
currentValue,这时候的cuurentValue为50,所以这次的total + currentValue值为80,也就是下一次total为80。

累加过程就是这样的,解释清楚第一次的total是什么值以及每次total用的是上一次累加值,应该就能看懂这reduce了

如何使用新方法

讲完了三个数组方法,接下来就是把它们投入使用的时候了
为了达成函数式编程,我们要知道它们的返回值

filter:返回新数组
map:返回新数组
reduce:返回一个值

那么我们是不是可以用filter返回的数组直接调用map,然后用map返回的数组直接调用reduce,最后把reduce返回的值交给一个sum即可
可以理解为:filter的返回值我们不去赋值给新数组而是拿来进行map方法,这样我们就可以少创建数组了

 let arr = [30, 50, 142, 305, 20, 16, 66, 77, 88]
    let sum = 0
    sum = arr.filter(function (n) {
        return n <= 60
      }) //这里就是filter的返回值。紧接着用这返回值进行map方法
      .map(function (n) {
        return n * 2
      }) //这就是map的返回值,紧接着用返回值进行reduce方法
      .reduce(function (pervValue, n) {
        return pervValue + n
      }) //最后将reduce返回值赋值给sum
    console.log(sum)

在这里插入图片描述

再一步优化

其实上面的链式函数,我们还可以给它进行优化,使用ES6新增的箭头函数

// 这是再简化,通过es6的箭头函数
// 怎么样,是不是感受到了函数式编程和es6的魅力
    let arr = [30, 50, 142, 305, 20, 16, 66, 77, 88]
    let sum = arr.filter(n => n <= 60).map(n => n * 2).reduce((preValue, n) => preValue + n)
    console.log(sum)

在这里插入图片描述
结果是一样的,我们从最开始的三个循环创建两个新数组的15行代码,变成了这简单的一行代码,这就是函数式编程和ES6的魅力!

这样看代码不好观看,让我们直接看看在编译器上,这一行代码是多么的漂亮在这里插入图片描述

总结

掌握这三个高级数组方法,妈妈再也不用担心我只会for循环啦!

当然ES6中新增的数组方法还有forEach,some,every,这几个方法非常简单了,这里就不提了

猜你喜欢

转载自blog.csdn.net/qq_46299172/article/details/107304567