

前言
我们在日常开发中,与接口打交道最多了,前端通过访问后端接口,然后将接口数据二次处理渲染到页面当中。
二次处理的过程是 考验 Coder 对 Array 是否熟练 以及 在 何种 场景下使用哪种方法处理最优 。
小编,在最近开发中就遇到了 Array 问题, 在处理复杂的业务需求时,没想到Array 有类似的方法,然后将方法 组合起来解决当下问题。
文章用下班时间肝了一周才写完,看完点赞、转发 是对我最大的支持。
遍历数组方法
不会改变原数组的遍历方法
forEach()
forEach() 方法按照升序为数组中每一项执行一次给定的函数。
语法
1arr.forEach(callback(currentValue , index , array) ,thisArg)
currentValue: 数组当前项值index: 数组当前项索引arr: 数组对象本身thisArg: 可选参数。当执行回调函数callback时,用作this的值。
注意
- 如果使用 箭头函数表达式来传入函数参数,
thisArg参数会被忽略,因为箭头函数在词法上绑定了this值。 forEach不会直接改变调用它的对象,但是那个对象可能会被callback函数改变。every不会改变原数组。
1//防盗贴:微信公众号: 前端自学社区 2 3const arr = [2,3,4,1,44] 4 5arr.forEach(val =>{ 6 console.log(`值为${val*2}`) 7 8}) 9console.log(`原数组为${arr}`); 10// 值为4 11// 值为6 12// 值为8 13// 值为2 14// 值为88 15// 原数组为2,3,4,1,44
reduce()
reduce()数组元素累计器,返回一个合并的结果值。
语法
1arr.reduce(callback(accumulator, currentValue, index, array), initialValue)
accumulator: 累计器,默认为数组元素第一个值currentValue: 当前值index: 当前元素索引 <font style="color:red">可选</font>array: 数组 <font style="color:red">可选</font>initialValue: 初始值 <font style="color:red">可选</font>
reduce 有两个参数,一个是回调函数,一个是初始值。
它有两种取值情况:
-
- 当提供了
initialValue初始值时, 那么accumulator的值为initialValue,currentValue的值为数组第一个值
- 当提供了
-
- 当没有提供
initialValue初始值时, 那么accumulator的值 为 数组第一个值,currentValue为第二个值。
- 当没有提供
注意
- 如果数组为空,且没有提供
initialValue初始值时,会抛出TypeError. - 如果数组有一个元素,且没有提供
initialValue或者 提供了initialValue,数组为空,那么唯一值被返回不会执行callback回调函数。
求和
1//防盗贴:微信公众号: 前端自学社区/ 2const arr = [1, 2, 3, 4] 3 4const sum = arr.reduce((accumulator, currentValue) => accumulator + currentValue, 10) 5 6console.log(sum) //20 7// accumulator 累计器 8// currentValue 当前值 9// initialValue 累计 初始值 为10 10 11//10 + 1 + 2 + 3 + 4 12 13 14## 注意 15// 回调函数第一次执行时,accumulator 和currentValue的取值有两种情况: 16// 如果调用reduce()时提供了initialValue,accumulator取值为initialValue,currentValue取数组中的第一个值; 17// 如果没有提供 initialValue,那么accumulator取数组中的第一个值,currentValue取数组中的第二个值。 18
计算对象中的值
要累加对象数组中包含的值,必须提供初始值,以便各个item正确通过你的函数。
1/* 2 * @Description: 3 * @Author: 微信公众号: 前端自学社区 4 * @Date: 2021-08-07 00:53:51 5 * @LastEditTime: 2021-08-07 00:53:51 6 * @LastEditors: Do not edit 7 */ 8const data = [ 9 { 10 date: '2021-8-1', 11 income: 200 12 }, 13 { 14 date: '2021-8-2', 15 income: 400 16 }, 17 { 18 date: '2021-8-3', 19 income: 300 20 }, 21] 22 23console.log(`总收入: ${data.reduce( (pre,currentValue) => pre + currentValue.income,0)}`); 24//总收入: 900
二维数组转一位数组
1const array = [[1,2],[3,4]] 2 3console.log(array.reduce((a,b) => a.concat(b))); 4//[ 1, 2, 3, 4 ]
find()
find() 返回满足特定条件的元素对象或者元素值, 不满足返回 undefined
语法
arr.find((element,index,array), thisArg)
element: 当前元素index: 当前元素索引 <font style="color:red">可选</font>array: 数组本身 <font style="color:red">可选</font>thisArg: 执行回调时用作this的对象。 <font style="color:red">可选</font>
1// 从数据中找出第一个满足特定条件的对象 2 3const data = [ 4 { 5 name:'张三', 6 article: 3 7 }, 8 { 9 name:'老王', 10 article: 9 11 }, 12 { 13 name:'老李', 14 article: 10 15 } 16] 17 18console.log(data.find(item => item.article > 9 )); 19 20// { name: '老李', article: 10 }
findIndex()
findIndex() 返回数组中符合条件的第一个元素的索引,没有,则返回 -1 。
语法
arr.findIndex((element,index,array), thisArg)
element: 当前元素index: 当前元素索引 <font style="color:red">可选</font>array: 数组本身 <font style="color:red">可选</font>thisArg: 执行回调时用作this的对象。 <font style="color:red">可选</font>
1const arr = [22,33,44,55] 2console.log(arr.findIndex(val => val > 33)); //2 3console.log(arr.findIndex(val => val > 99)); //-1
key()
key() 返回一个新的Array Iterator对象,该对象包含数组中每个索引的键。
语法
1keys()
注意
- 如果数组中有空原元素,在获取key 时, 也会加入遍历的队列中。
1const inputModal = [ 2 { 3 name:'' 4 }, 5 { 6 age:'' 7 }, 8 { 9 hobby:'' 10 } 11] 12for(const key of inputModal.keys()){ 13 console.log(key) 14} 15// 0 16// 1 17// 2 18 19const arr = [1,2,,3] 20for(const key of arr.keys()){ 21 console.log(key); 22} 23// 0 24// 1 25// 2 26// 3 27 28 29//Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组 30// 所以 Object.keys(arr) = [ '0', '1', '3' ] 31for(const key of Object.keys(arr)){ 32 console.log(key); 33} 34// 0 35// 1 36// 3
values()
values() 方法返回一个新的 Array Iterator 对象,该对象包含数组每个索引的值。
语法
1arr.values()
<hr/>1const Color = ['red','yelloe','orange'] 2 3for(val of Color.values()){ 4 console.log(val); 5} 6// red 7// yelloe 8// orange
返回 布尔值
every()
every 用来判断数组内所有元素是否符合某个条件,返回 布尔值
语法
1arr.every(callback(currentValue , index , array) ,thisArg)
currentValue: 数组当前项值 <font style="color:red">必须</font>index: 数组当前项索引 <font style="color:red">可选</font>arr: 数组对象本身<font style="color:red">可选</font>thisArg: 可选参数。当执行回调函数callback时,用作this的值。<font style="color:red">可选</font>
注意
- 当所有的元素都符合条件才会返回
true every不会改变原数组。- 若传入一个空数组,无论如何都会返回
true。
1//防盗贴:微信公众号: 前端自学社区 2 3const arr = [2,3,4,1,44] 4 5console.log(arr.every(val => val > 0 )); //true 6 7console.log(arr.every(val => { val > 2 })) //false 8
some()
some() 用来判断数组元素是否符合某个条件,只要有一个元素符合,那么返回 true.
语法
1arr.some(callback(currentValue , index , array) ,thisArg)
currentValue: 数组当前项值 <font style="color:red">必须</font>index: 数组当前项索引 <font style="color:red">可选</font>arr: 数组对象本身<font style="color:red">可选</font>thisArg: 可选参数。当执行回调函数callback时,用作this的值。<font style="color:red">可选</font>
注意
some()被调用时不会改变数组。- 如果用一个空数组进行测试,在任何情况下它返回的都是
false。 some()在遍历时,元素范围已经确定,在遍历过程中添加的元素,不会加入到遍历的序列中。
1const arr = [2,3,4,1,44] 2 3console.log(arr.some(val => val > 2)) //true 4console.log([].some(val => val > 2 )); //false 5 6 7const newList = [11,22,33,44] 8console.log(newList.some(val => { 9 newList.push(55) 10 newList.push(66) 11 val > 55 12})); //false
不改变原有数组,形成新的数组
filter()
filter() 用来遍历原数组,过滤拿到符合条件的数组元素,形成新的数组元素。
语法
1arr.some(callback(currentValue , index , array) ,thisArg)
currentValue: 数组当前项值 <font style="color:red">必须</font>index: 数组当前项索引 <font style="color:red">可选</font>arr: 数组对象本身<font style="color:red">可选</font>thisArg: 可选参数。当执行回调函数callback时,用作this的值。<font style="color:red">可选</font>
注意
filter不会改变原数组,它返回过滤后的新数组。filter()在遍历时,元素范围已经确定,在遍历过程中添加的元素,不会加入到遍历的序列中。
1const arr = [11,22,33,44,55,66] 2 3 4console.log(arr.filter(val => val > 44 )) 5console.log(`原数组为${arr}`); 6 7// [ 55, 66 ] 8// 原数组为11,22,33,44,55,66
map()
map() 创建一个新的数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
语法
1arr.map(callback(currentValue , index , array) ,thisArg)
currentValue: 数组当前项值 <font style="color:red">必须</font>index: 数组当前项索引 <font style="color:red">可选</font>arr: 数组对象本身<font style="color:red">可选</font>thisArg: 可选参数。当执行回调函数callback时,用作this的值。<font style="color:red">可选</font>
注意
map不修改调用它的原数组本身map()在遍历时,元素范围已经确定,在遍历过程中添加的元素,不会加入到遍历的序列中。
<hr/>1const arr = [1,2,3,4] 2 3console.log(arr.map(val => val*3 )) // [ 3, 6, 9, 12 ] 4console.log(arr) // [ 1, 2, 3, 4 ]
数组 CRUD
改变原数组方法
reverse()
reverse() 方法将数组中元素的位置颠倒,并返回该数组。数组的第一个元素会变成最后一个,数组的最后一个元素变成第一个。该方法会改变原数组。
1const arr = [1,2,3] 2 3console.log(arr.reverse(11,22,33)) //[ 3, 2, 1 ]
sort()
sort() 方法采用 原地算法进行排序并返回数组。默认排序顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列
原地算法是一个使用辅助的数据结构对输入进行转换的算法。但是,它允许有少量额外的存储空间来储存辅助变量。当算法运行时,输入通常会被输出覆盖。原地算法仅通过替换或交换元素来更新输入序列。
1const arr = [23,11,33,44,1] 2 3console.log(arr.sort()) //[ 1, 11, 23, 33, 44 ] 4 5 6const arr = [23,11,33,44,1000000000] 7 8console.log(arr.sort()) 9// [ 1000000000, 11, 23, 33, 44 ]
删除元素
shift()
shift() 方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。
语法
1arr.shift()
注意
- 从数组中删除的元素; 如果数组为空则返回
undefined
1const data = [ 2 { 3 id:1, 4 name:'前端' 5 }, 6 { 7 id:2, 8 name:'后端' 9 }, 10 { 11 id:3, 12 name:'移动端' 13 }, 14 { 15 id:4, 16 name:'嵌入式开发' 17 }, 18] 19 20const deleObj = data.shift() 21 22 23 24console.log('==============删除后的元素======================'); 25console.log(data); 26console.log('=================删除后的元素==================='); 27 28 29console.log('===============被删除的元素====================='); 30console.log(deleObj); 31console.log('================被删除的元素===================='); 32 33// ==============删除后的元素====================== 34// [ 35// { id: 2, name: '后端' }, 36// { id: 3, name: '移动端' }, 37// { id: 4, name: '嵌入式开发' } 38// ] 39// =================删除后的元素=================== 40 41 42// ===============被删除的元素===================== 43// { id: 1, name: '前端' } 44// ================被删除的元素====================
pop()
pop()方法从数组中删除最后一个元素,并返回该元素的值。此方法更改数组的长度。
用法和 shift 类似。
语法
1arr.pop()
注意
- 从数组中删除的元素; 如果数组为空则返回
undefined
1const data = [ 2 { 3 id:1, 4 name:'前端' 5 }, 6 { 7 id:2, 8 name:'后端' 9 }, 10 { 11 id:3, 12 name:'移动端' 13 }, 14 { 15 id:4, 16 name:'嵌入式开发' 17 }, 18] 19 20const deleObj = data.pop() 21 22 23 24 25console.log(data); 26// [ 27// { id: 1, name: '前端' }, 28// { id: 2, name: '后端' }, 29// { id: 3, name: '移动端' } 30// ] 31console.log(deleObj); 32// { id: 4, name: '嵌入式开发' }
splice()
splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。
语法
1array.splice(start,deleteCount, [item1,item2....])
start: 开始的索引deleteCount: 删除的个数 <font style="color:red">可选</font>[item1,item2 .....];从开始的索引进行 添加的增加和替换的元素, <font style="color:red">可选</font>
注意
-
由被删除的元素组成的一个数组。如果只删除了一个元素,则返回只包含一个元素的数组。如果没有删除元素,则返回空数组。
-
如果只传递了开始的索引位置,则会删除索引后的所有元素对象
1const data = [ 2 { 3 id:1, 4 name:'前端' 5 }, 6 { 7 id:2, 8 name:'后端' 9 }, 10 { 11 id:3, 12 name:'移动端' 13 }, 14 { 15 id:4, 16 name:'嵌入式开发' 17 }, 18] 19data.splice(1) 20console.log(data) 21// [ { id: 1, name: '前端' } ]
从索引为 2 开始, 删除 1 个数组元素对象,添加两个数组元素对象
1const data = [ 2 { 3 id:1, 4 name:'前端' 5 }, 6 { 7 id:2, 8 name:'后端' 9 }, 10 { 11 id:3, 12 name:'移动端' 13 }, 14 { 15 id:4, 16 name:'嵌入式开发' 17 }, 18] 19 20 21data.splice(2,1,...[{id:5,name:'人工智能'},{id:6,name:'大数据开发'}]) 22 23console.log(data); 24// [ 25// { id: 1, name: '前端' }, 26// { id: 2, name: '后端' }, 27// { id: 5, name: '人工智能' }, 28// { id: 6, name: '大数据开发' }, 29// { id: 4, name: '嵌入式开发' } 30// ]
增加元素
splice()
上面已经有介绍
push()
push() 方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度。
语法
1arr.push(element1, ..., elementN)
1const data = [ 2 { 3 id:1, 4 name:'前端' 5 }, 6 { 7 id:2, 8 name:'后端' 9 }, 10] 11 12console.log(data.push({id:3,name:'移动端'})) //3
合并数组
1const data = [ 2 { 3 id:1, 4 name:'前端' 5 }, 6 { 7 id:2, 8 name:'后端' 9 }, 10] 11 12 13var obj = [ 14 { 15 id:4, 16 name:'嵌入式开发' 17 }, 18] 19 20// 相当于 data.push({id:4,name:'嵌入式开发'}); 21Array.prototype.push.apply(data, obj); 22 23console.log(data); 24 25[ 26 { id: 1, name: '前端' }, 27 { id: 2, name: '后端' }, 28 { id: 4, name: '嵌入式开发' } 29]
unshift()
unshift() 方法将一个或多个元素添加到数组的开头,并返回该数组的新长度。
1const arr = [1,2,3] 2 3 4 5console.log(arr.unshift(11,22,33)) //6 6console.log(arr) //[ 11, 22, 33, 1, 2, 3 ]
不改变原数组元素方法
indexOf()
indexOf()方法返回可以在数组中找到给定元素的第一个索引,如果不存在,则返回 -1。
语法
1indexOf(searchElement) 2indexOf(searchElement, fromIndex)
searchElement: 要查找的元素fromIndex: 按指定的索引进行查找出现的指定元素的第一个索引。 <font style="color:red">可选</font>- 如果索引大于或等于数组的长度,则返回-1
- 如果提供的索引值为负数,则将其视为距数组末尾的偏移量
- 如果提供的索引为负数,仍然从前到后搜索数组
- 如果提供的索引为 0,则将搜索整个数组。
- 默认值:0(搜索整个数组)。
1const arr = [1,1,2,3,4,5,4,4,6] 2 3console.log(arr.indexOf(3)); //3 4console.log(arr.indexOf(9)); //-1 5 6 7console.log(arr.indexOf(3,4)); //-1 8//从索引为 4 的元素进行查找 3, 显然后面没有3 , 返回 -1
数组去重
创建一个新的空数组,通过indexOf 来判断空数组是否第一次存在某个元素,
- 不存在则返回 [ < 0 ] ,
push到空数组中.
1const newArr = [] 2arr.forEach(val => { 3 if(newArr.indexOf(val) < 0){ 4 newArr.push(val) 5 } 6}) 7console.log(newArr); 8// [ 1, 2, 3, 4, 5, 6 ] 9
lastIndexOf()
lastIndexOf() 查找数组中元素最后一次出现的索引,如未找到返回-1。
如果不存在则返回 -1。从数组的后面向前查找,从 fromIndex 处开始。
语法
1arr.lastIndexOf(searchElement, fromIndex)
searchElement: 要查找的元素fromIndex: 按指定的索引进行查找出现的指定元素的第一个索引。 <font style="color:red">可选</font>- 从指定的索引位置 逆向 查找
- 默认为数组的长度减 1(
arr.length - 1),即整个数组都被查找。 - 如果该值大于或等于数组的长度,则整个数组会被查找。
- 如果为负值,数组仍然会被从后向前查找。
- 如果该值为负时,其绝对值大于数组长度,则方法返回 -1,即数组不会被查找。
注意
lastIndexOf使用的是 严格相等 === 比较searchElement和数组中的元素。
1const arr = [1,1,2,3,4,5,4,4,6] 2 3console.log(arr.lastIndexOf(4)); //7 4 5console.log(arr.lastIndexOf(4,11)); 6//7 指定的查找的索引 大于 数组的长度, 会进行整个数组查找 7 8console.log(arr.lastIndexOf(4,-33)); 9// -1 指定的索引为负数,且绝对值大于数组长度, 则返回 -1 10 11console.log(arr.lastIndexOf(4,-5)); 12//4 指定的索引为负数,且绝对值小于数组长度, 则会 从向前进行查找
inCludes()
includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回false。
语法
1arr.includes(searchElement, fromIndex)
-
searchElement: 要查找的元素查找时,区分大小写
-
fromIndex: 按指定的索引进行查找出现的指定元素的第一个索引。 <font style="color:red">可选</font>- 从指定的索引进行查找
- 如果为负值,则按升序从
array.length + fromIndex的索引开始搜 - 如果
fromIndex大于等于数组的长度,则会返回false,且该数组不会被搜索。 - 默认为0
1const arr = [1,1,2,3,4,5,4,4,6] 2 3console.log(arr.includes(4)); //true 4 5console.log(arr.includes(4,66)); //false 6 7console.log(arr.includes(1,-1)); //false
concat()
concat() 方法用于合并两个或多个数组。
语法
1var new_array = old_array.concat([arr1][arr2])
注意
-
concat方法不会改变this或任何作为参数提供的数组,而是返回一个浅拷贝,它包含与原始数组相结合的相同元素的副本- 对象引用(而不是实际对象):
concat将对象引用复制到新数组中。 原始数组和新数组都引用相同的对象。 也就是说,如果引用的对象被修改,则更改对于新数组和原始数组都是可见的。 这包括也是数组的数组参数的元素。 - 数据类型如字符串,数字和布尔(不是
String,Number和Boolean) 对象):concat将字符串和数字的值复制到新数组中。
- 对象引用(而不是实际对象):
1let arr1 = [1,2,3] 2let arr2 = [4,5,6] 3let arr3 = [[1,2],[3,4]] 4console.log(arr1.concat(arr2)); 5//[ 1, 2, 3, 4, 5, 6 ] 6 7// 嵌套合并 8console.log(arr1.concat(arr2).concat(arr3)); 9// [ 1, 2, 3, 4, 5, 6, [ 1, 2 ], [ 3, 4 ] ] 10 11 12let obj1 = [{a:1},{b:2}] 13let obj2 = [{c:3},{d:4}] 14let obj3 = obj1.concat(obj2) 15console.log(obj3); 16//[ { a: 1 }, { b: 2 }, { c: 3 }, { d: 4 } ] 17 18 19obj1[0].a = 4 //改变obj[0]对象值,会直接影响合并后的数组,因为是浅拷贝 20console.log(obj3); 21//[ { a: 4 }, { b: 2 }, { c: 3 }, { d: 4 } ]
toString()
toString() 返回一个字符串,表示指定的数组及其元素。
当一个数组被作为文本值或者进行字符串连接操作时,将会自动调用其 toString 方法。
对于数组对象,toString 方法连接数组并返回一个字符串,其中包含用逗号分隔的每个数组元素。
语法
1arr.toString()
1const arr = [1,2,3] 2 3console.log(arr.toString()); //1,2,3
join()
join()方法通过连接数组元素用逗号或指定的分隔符字符串分隔,返回一个字符串。
如果数组只有一项,则将在不使用分隔符的情况下返回该项。
语法
1join() 2join(separator)
separator: 指定的分割的 字符 <font style="color:red">可选</font>
1const arr = ['2021','08','08'] 2 3console.log(arr.join()); //2021,08,08 4console.log(arr.join('-')); //2021-08-08 5console.log(arr.join('/')); //2021/08/08
slice()
slice() 方法返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。
语法
1arr.slice(begin, end)
-
begin: 指定截取的开始索引 <font style="color:red">可选</font>- 默认从0 开始
- 如果
begin为负数,则以数组末尾开始 的 绝对值开始截取slice(-2)末尾第2个元素 - 如果
begin超出原数组的索引范围,则会返回空数组。
-
end: 指定截取的结束索引 <font style="color:red">可选</font>- 如果
end被省略,则slice会一直提取到原数组末尾。 - 如果
end大于数组的长度,slice也会一直提取到原数组末尾。 - 如果
end为负数, 则它表示在原数组中的倒数第几个元素结束抽取。
- 如果
1const arr = [11,22,33,44,55,66,77,88] 2 3console.log(arr.slice(1,4)); 4// 应该返回 索引 1 - 3 的数组元素 5// [ 22, 33, 44 ] 6 7 8console.log(arr.slice(-4,2)) //[] 9 10console.log(arr.slice(-4)); //[ 55, 66, 77, 88 ] 11 12 13console.log(arr.slice(0,-1)); 14// [ 15// 11, 22, 33, 44, 16// 55, 66, 77 17// ]
参考文献
最后
文章用下班时间肝了一周,写作不易,文中的内容都是 参考 MDN 文档 。 如果喜欢的话可以点赞👍👍👍关注,支持一下,希望大家可以看完本文有所收获 !
<img src="https://img-hello-world.oss-cn-beijing.aliyuncs.com/imgs/497ff10ccd161003e02b5b4bbdd8548e.png">