我真的了解数组嘛
在日常的业务开发中,我们通常需要对后端返回的数据解构进行处理,得到我们想要的格式,而其中比较常见的场景便是对数组的操作。最开始用的时候只是看他人写法或者去菜鸟教程大致看一下demo,对于一些方法之间的区别、是否运用得合理没有明确的概念。还有一些方法(比如reduce)是之前有同学推荐过,但是一直没去用的,这次希望也能一网打尽。因此本次博客希望对数组相关的方法进行一个比较系统的总结,希望通过这次学习我能真正地了解数组,最好也不要再用一次“gugou”一次了QAQ。
1.some 和 find
当我们需要在数组中寻找一个元素时,我们通常会想到Array.find。它需要一个回调函数,并返回符合条件的第一个元素。然而,当我们仅仅需要知道数组中是否存在符合条件的元素时,Array.some或许是一个更好的办法,因为它返回的是一个布尔值。
1 | arr.find(callback, thisArg) |
callback 是数组每一项都会执行的回调函数,它接受三个参数:
value 当前正在被处理的项
index 当前项的索引
array 数组本身
thisArg 可选,用来当做fn函数内的this对象
说到find,在es6中它有一个兄弟Array.findIndex。它的入参和find基本一致,只不过它返回的是第一个符合条件的项在数组中的位置,如果没有符合条件的则返回-1。
2.find 和 filter
filter的中文意思是过滤,正如其名字所言,它的功能便是通过回调函数过滤数组,并将过滤后的项作为一个新数组返回。
看到上文中我们丢下find使用some的场景,find有些不服气。find曰:看看下面这个场景——我们需要通过一个唯一的ID 为过滤条件去过滤一个数组。如果此时用Array.filter的话,它将会遍历整个数组,当数组项很多时会多次执行回调函数。而明显本场景最终将只有一个符合条件的数据,我们用find在搜寻到第一个符合条件的结果后立即返回。从性能的角度上来说,让我们恭喜find!
3.indexOf 和 includes
Array.indexOf这个方法我们都狠熟悉了,它返回第一个指定元素的下标,如果不存在则返回-1。如果我们不需要知道下标,可以使用直接返回布尔值的 Array.includes。说到返回布尔值,你们有没有想起上面提到的some呢。注意了,注意了,一定要分清楚哦。Array.includes 的第一个入参是一个值, Array.some 的第一个入参是回调函数。includes简单,而some方法可以用来处理较为复杂的数组项哦。
4.reduce来咯
我们什么情况下可以使用reduce呢,有一个比较容易记的方法。当一个场景中我们需要先用Array.filter对数组进行过滤操作,然后对其进行遍历,用map方法返回一个新数组。此时我们可以用Array.reduce方法,一样的味道,更好的配方哦。Array.reduce方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
1 | arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue]) |
callback 接受四个参数,分别是:accumulator,累加器累加回调的返回值; currentValue,数组中正在处理的元素;currentIndex(可选),数组中正在处理的当前元素的索引;array(可选),调用 reduce() 的数组。initialValue 为可选参数,作为第一次调用 callback 函数时的第一个参数的值。方法的返回值是函数累计处理的结果。
PS:这里通过查阅资料还得知了mdn的语法,可选参数用括号+逗号 [,
表示,而必需的参数只用逗号,
。
光说不练假把式,让我们来进入实战!
emmm我们来模拟一个后端童鞋返回的数据。
1 | [{ |
Round 1
先从简单的开始,我们来统计number的总和吧。
1 | arr.reduce((total, { number }) => { |
Round 2
加大难度,我们来将数组每项转换为字符串,项之间用空格隔开。
1 | arr.reduce((str, { id, name }) => { |
Round 3
boss关,我们来将数组转换成 key value 的对象形式。
1 | arr.reduce((obj, { id, ...value }) => { |
最终返回的结果为
1 | { |
闯关成功,希望我们能学以致用,在今后的工作中很好滴运用这个方法😄
5.forEach 和 map
首先,我们可以明确的是,forEach()方法不会返回执行结果,而是undefined,而map()方法会得到一个新的数组并返回。forEach()允许callback更改原始数组的元素。map()返回新的数组。
项目中有很多地方直接在map方法的回调函数中修改原始数组的值,其实这样做是不建议的。这么做能行得通是因为js中的数组是引用类型,所以可以利用类似指针的特性通过改变另一个变量去修改原始的值。但是!但是!map方法体现的是数据不可变的思想。该思想认为所有的数据都是不能改变的,只能通过生成新的数据来达到修改的目的,因此直接对数组元素或对象属性进行操作的行为都是不可取的。这种思想其实有很多好处,最直接的就是避免了数据的隐式修改。我们来举个栗子。
1 | let arr = [{ |
6.展望
emmm可能还有很多数组的方法没有照顾周全,如果以后还遇到一些问题和一些对数组巧妙操作的方法,我们再记录。还有性能上的问题,也值得我们去探讨。