数组操作方法
一、shift和unshift
- shift:删除数组中的第一个元素
- unshift:在数组的开头添加一个或更多的元素
代码实现
let array = ["a", "d", "v", "c","g"]
console.log(array.pop())
console.log(array)
console.log(array.push('j','k'))
console.log(array)
运行结果
二、pop和push
- pop:删除数组中的最后一个元素
- push:在数组的末尾添加一个或更多的元素
代码实现
let array = ["a", "d", "v", "c","g"]
console.log(array.pop())
console.log(array)
console.log(array.push('j','k'))
console.log(array)
运行效果
三、delete
delete:通过下标删除数组,删除后对应下标变为空,数组整体长度不变。
代码示例
let arr = [1,2,3,4,5];
delete arr[2];
console.log(arr);
运行效果
注意: 此时输出arr[2]的结果为undefined
四、splice()
splice:希望删除元素后,元素的位置会被后继的元素填补,数组的长度变短。
这个时候,我们就需要splice()方法。且需要提前说明的是,splice()方法的功能相当丰富,并非只能删除元素
1、删除一个元素
设置splice两个参数,第一个为起始下标。
代码实现
let arr = [1,2,3,4,5]
arr.splice(0,1);//删除掉第一个元素 1
console.log(arr)
运行效果
2、删除多个元素
删除多个元素和删除一个元素用法相同,只需要将第二个参数改为指定数量就可以了。
代码实现
let arr = [1,2,3,4,5];
arr.splice(0,3);//删除前三个元素
console.log(arr);//[4,5]
运行效果
3、截断数组
如果我们只提供一个参数start,那么就会删除数组start位置后面的所有元素。
代码实现
let arr = [1,2,3,4,5]
arr.splice(2);//删除从下标为2以及后面的所有元素
console.log(arr);//[1,2]
运行效果
4、元素替换
如果我们提供了超过两个参数,那么就可以替换数组元素
代码展示
let arr = [1,2,3,4,5];
arr.splice(0,2,'a','b,'c');
console.log(arr);//['a','b,'c',3,4,5]
执行效果
5、元素插入
如果我们把第二个参数(删除数量)改为0,那么就可以只插入元素,不删除元素
代码展示
let arr = [1,2,3]
arr.splice(0,0,'x','y','z')
console.log(arr);//['x','y','z'1,2,3]
执行效果
6、返回值
splice()函数可以被删除的元素数组。
代码展示
let arr = [1,2,3,4,5]
let res = arr.splice(0,3,'x','y')
console.log(arr)//['x','y',4,5]
console.log(res)//[1,2,3]
执行效果
7、负索引
我们可以使用负数指示开始操作元素的位置(-1表示从最后一个开始)
代码展示
let arr = [1,2,3,4,5]
arr.splice(-1,1,'x','y','z')
console.log(arr)//[1,2,3,4,'x','y','z']
执行效果
五、slice()
slice()方法可以截取指定范围的数组,语法如下:
arr.slice([start],[end])
返回一个新数组,新数组从start开始,到end结束,但是不包括end。
代码展示
let arr = [1,2,3,4,5]
console.log(arr.slice(2,5))//[3,4,5]
console.log(arr.slice(1,3))//[2,3]
执行效果
slice()同样可以使用负数下标
代码展示
let arr = [1,2,3,4,5]
console.log(arr.slice(-3))//[3,4,5]
console.log(arr.slice(-5,-1))//[1,2,3,4]
执行效果
注意
如果只为slice()方法提供一个参数,就会和splice()一样截断到数组末尾。
六、concat()
concat()函数可以将多个数组或者其他类型的值拼接称一个长数组
arr.concat(e1, e2, e3)
以上代码将返回一个新的数组,新数组由arr拼接e1、e2、e3而成。
代码展示
let arr = [1,2,3]
console.log(arr.concat([4,5],6,7,[8,9]))
执行效果
注意: 即使它们看起来和对象一样,仍然会被作为一个整体插入到数组中。
代码展示
let arr = [1,2]
let obj = {1:'1',2:2}
console.log(arr.concat(obj))
执行效果
但是,如果对象具有Symbol.isConcatSpreadable属性,就会被当作数组处理。
代码展示
let arr = [1,2]
let obj = {0:'x',
1:'y',
[Symbol.isConcatSpreadable]:true,
length:2
}
console.log(arr.concat(obj))
执行效果
七、forEach()
遍历整个数组,为每个数组元素提供一个操作函数
代码展示
let arr1= [1,2,3,4,5]
arr1.forEach(itm)=>{
console.log(itm)
})
let arr = [1,2,3,4,5]
arr.forEach((itm,idx,array)=>{
console.log(`arr[${idx}]`+`是数组`+` [${array}] `+`中的`+` ${itm}`)
})
执行效果
八、indexOf、lastIndexOf、includes
类似于字符串,indexOf、lastIndexOf、includes可与查询数组中指定元素的下标:
-
arr.indexOf(itm,start):从start位置开始搜索itm,如果找到返回下标,否则返回-1; -
arr.lastIndexOf(itm,start):倒序查找整个数组,直至start处,返回第一个查到的下标(也就是数组最后一个匹配项),找不到返回-1; -
arr.includes(itm,start):从start位置开始搜索itm,找到返回true,否则返回false;
代码展示
let arr = [1,2,3,4,5,6,"7","8","9",0,0,true,false]
console.log(arr.indexOf(0))//9
console.log(arr.lastIndexOf(0))//10
console.log(arr.includes(10))//false
console.log(arr.includes(9))//false
执行效果
NaN的处理
NaN是一个特殊的数字,三者在处理NaN有细微差别
代码展示
let arr = [NaN,1,2,3,NaN]
console.log(arr.includes(NaN))//true
console.log(arr.indexOf(NaN))//-1
console.log(arr.lastIndexOf(NaN))//-1
// 产生这种结果的原因和`NaN`本身的特性有关,即`NaN`不等于任何数字,包括他自己。
执行结果
九、find、findIndex
在编程过程中常常会遇到对象数组,而对象是不能直接使用===比较的,个时候就要使用find和findIndex方法,语法如下:
let result = arr.find(function(item,idx,array){
//item数组元素
//idx元素下标
//array数组本身
//传入一个判断函数,如果该函数返回true,就返回当前对象item
})
举个栗子:假如我们需要查找name属性等于huge的对象
代码展示
let arr =[
{id:1,name:'huge'},
{id:2,name:'jindong'},
{id:3,name:'liangchaowei'},
]
let huge = arr.find(function(item,idx,array){
if(item.name == 'huge')return true;
})
console.log(huge)
// 果没有符合条件的对象,就回返回undefined
执行效果
arr.findIndex(func)的用途和arr.find(func)几乎相同,唯一不同的地方在于,arr.findIndex返回符合条件对象的下标而不对象本身,找不到返回-1。
十、filter
find和findIndex只能查找一个满足要求的对象,如果一个数组中存在多个满足要求的对象,就需要使用filter方法,语法如下:
let results = arr.filter(function(itm,idx,array){
//和find的用法相同,不过会返回符合要求的对象数组
//找不到返回空数组
})
举个栗子
代码展示
let arr =[
{id:1,name:'huge'},
{id:2,name:'jindong'},
{id:3,name:'liangchaowei'},
]
let res = arr.filter(function(itm,idx,array){
if(itm.name == 'huge' || itm.name == 'jindong')return true;
})
console.log(res)
执行效果
十一、map
arr.map方法可以对数组的每个对象都调用一个函数,然后返回处理后的数组,这是数组最有用的、最重要的方法之一。语法如下:
let arrNew = arr.map(function(itm,idx,array){
//返回新的结果
})
举个栗子:返回字符串数组对应的长度数组
代码展示
let arr = ['I','am','a','handsomeboy']
let arrNew = arr.map((itm)=>itm.length)
console.log(arrNew)
执行效果
十二、sort
arr.sort对数组进行原地排序,并返回排序后的数组,但是,由于原数组已经发生了改变,返回值实际上没有什么意义。所谓原地排序,就是在原数组空间内排序,而不是新建一个数组
举栗子
1、字母排序
代码展示
let arr = ['a','c','b']
arr.sort()
console.log(arr)
执行效果
注意
默认情况下sort方法是以字母序进行排序的,也就是适用于字符串排序,如果要排列其他类型的数组,需要自定义比较方法
2、数字排序
代码展示
let arr = [1,3,2]
arr.sort(function(a,b){
if(a > b)return 1;
if(a < b)return -1;
return 0;
})
执行效果
sort函数内部采用了快速排序算法,也可能是timsort算法,但是这些我们都不需要关心,我们只需要关注比较函数就可以了。
比较函数可以返回任何数值,正数表示>,负数表示<,0表示等于,所以我们可以简化数字比较方法:
let arr = [1,3,2]
arr.sort((a,b)=> a - b)
如果想要逆序排列只需要交换一下a和b的位置既可以了:
let arr = [1,3,2]
arr.sort((a,b)=> b - a)
3、字符串排序
别忘了字符串比较要使用str.localeCompare(str1)方法喔
代码展示
let arr = ['asdfas','success','failures']
arr.sort((a,b)=>a.localeCompare(b))
执行效果
十三、reverse
arr.reverse用于逆序数组
代码展示
let arr = [1,2,3]
arr.reverse()
console.log(arr)
执行效果
十四、str.split()和arr.join()
还记得字符串分割函数吗?字符串分割函数可以将字符串分割成一个字符数组:
let str = 'xiaoming,xiaohong,xiaoli'
let arr = str.split(',')//['xiaoming','xiaohong','xiali']
冷门知识,split函数有第二个参数,可以限制生成数组的长度
let str = 'xiaoming,xiaohong,xiaoli'
let arr = str.split(',',2)//['xiaoming','xiaohong']
arr.join()方法用途和split方法相反,可以将一个数组组合成一个字符串。
举个栗子
代码展示
let arr = [1,2,3]
let str = arr.join(';')
console.log(str)
执行效果
十五、reduce、reduceRight
arr.reduce方法和arr.map方法类似,都是传入一个方法,然后依次对数组元素调用这个方法,不同的地方在于,app.map方法在处理数组元素时,每次元素调用都是独立的,而arr.reduce会把上一个元素的调用结果传到当前元素处理方法中。语法如下:
let res = arr.reduce(function(prev,itm,idx,array){
//prev是上一个元素调用返回的结果
//init会在第一个元素执行时充当上一个元素调用结果
},[init])
如何实现一个数字组成的数组元素和呢?map是没有办法实现的,这个时候就需要使用arr.reduce
代码展示
let arr = [1,2,3,4,5]
let res = arr.reduce((sum,itm)=>sum+itm,0)
console.log(res)
执行效果
arr.reduceRight和arr.reduce用途相同,只不过从右往左对元素调用方法。
十六、Array.isArray()
数组是对象的一种特例,使用typeof无法准确的分辨二者的区别
console.log(typeof {})//object
console.log(typeof [])//object
二者都是对象,我们需要使用Array.isArray()方法进一步做判断
代码展示
console.log(Array.isArray({}))//false
console.log(Array.isArray([]))//true
执行效果
十七、some、every
arr.some(func)和arr.every(func)方法用于检查数字,执行机制和map类似
some
对每个数组元素执行传入的方法,如果方法返回true,立即返回true,如果所有的元素都不返回true,就返回false。
every
对数组的每个元素执行传入的方法,如果所有元素都返回true,则返回true,否则返回false。
举个例子
代码展示
let arr = [1,2,3,4,5]
//判断数组是否存在大于2的元素
console.log(arr.some((itm)=>{
if(itm > 2)return true;
}))
//判断是否所有的元素都大于2
console.log(arr.every((itm)=>{
if(itm > 2)return true;
}))
执行效果
十八、this.Arg
在所有的数组方法中,除了sort,都有一个不常用固定参数thisArg,语法如下:
arr.find(func,thisArg)
arr.filter(func,thisArg)
arr.map(func,thisArg)
如果我们传入了thisArg,那么它就会在func中变为this。
这个参数在常规情况下是没什么用处的,但是如果func是一个成员方法(对象的方法),而且方法中使用了this那么thisArg就会非常有意义。
举个例子
代码展示
let obj = {
num : 3,
func(itm){
console.log(this)
return itm > this.num;//查找大于3的数字
}
}
let arr = [1,2,3,4,5,6,7]
let newArr = arr.filter(obj.func,obj)
console.log(newArr)
执行效果
注意
这里我们可以看到,func中输出的this就是我们传入的thisArg值。
如果我们使用对象成员方法,同时不指定thisArg的值,就会造成this为undefined,从而导致程序错误。
总结
作为一种非常常用的引用类型,其中包含很多的方法,当我们熟练掌握这些方法之后,在一些复杂的功能上就能解决起来游刃有余。