定义数组的形式
定义数组的形式有多种,别离如下
- let array=[] (字面量)
- let array=new Array()
- let array=new Array([length]) length示意长度
- let array=new Array(arg1,arg2,arg3....)
let array=[]; // 初始化一个空数组let array2=new Array(); // 初始化一个空数组let array3=new Array(10); // 初始化一个长度为10的数组,数组的每一项都是emptylet array4=new Array(10,20,30,40);// 初始化一个长度为4的数组,数组的项别离为 10,20,30,40
其中在开发中,let array=[]应用的最多,也是举荐的。
数组的增删改查
数组的新增
定义一个数组之后须要向数组中增加对应的项,这里先介绍几种简略的解决办法。
- array[index]=xxx
- array[array.length]=xxx
let array=[];array[0]=100;array[1]=200;console.log(array); // 100, 200let array2=[10,20];array2[array.length]=30;console.log(array2); // 10 20 30
数组的批改
如果须要批改的项存在则执行批改操作,不存在执行新增操作
let array=[];array[0]=100;array[1]=200;console.log(array); // 100, 200array[1]=300; // 项存在,执行批改操作console.log(array); // 100 300
数组的删除
arr.length=xxx xxx小于数组的长度就能够删除项
let array=[];array[0]=100;array[1]=200;console.log(array); // 100, 200array.length=0;console.log(array); // []
数组的查问
- 循环遍历每一项,for循环,forEach循环等等
- 下标(索引)获取,array[index] 其中index示意索引
let array=[10,20,30,40,50];console.log(array[0]); // 获取数组的第一项 10for(let i=0;i<array.length;i++){ console.log(array[i]); // 遍历数组的每一项 10,20,30,40,50}
检测数组的办法和数组的length属性
初始化数组之后,数组自带有一个length属性,示意数组的长度,这里就不再进行介绍了,检测数组的办法有instanceof和Array.isArray()
let array=[10,20,30,40,50];console.log(Array.isArray(array)); // trueconsole.log(array instanceof Array); // true
咱们晓得数组是对象,既然是对象就必然离不开属性(length)和办法,对于属性length,就那啥了,你们懂的,次要介绍一下数组的办法,这里分为ES5数组罕用的办法和ES6数组的办法。
ES5数组罕用的办法
转换方法
- Array.toString():将数组变成由逗号宰割的字符串
- Array.valueOf():返回数组自身
let array=[10,20,30,40,50];console.log(array.toString()); // 10,20,30,40,50console.log(array.valueOf()); // [10,20,30,40,50]
栈办法(遵循后进先出的准则)
- Array.push():将一个或多个元素增加到数组的开端,并返回该数组的新长度
- Array.pop(): 从数组中删除最初一个元素,并返回该元素的值。此办法更改数组的长度
let array=[];array.push(10,20,30,40,50,60);console.log(array);// 10,20,30,40,50,60let item=array.pop();console.log(item);// 60console.log(array);// 10,20,30,40,50
留神:数组的办法不反对推入整个数组,例如arr.push([1,2,3])不会是1,2,3,[1,2,3]只会作为数组中的一项,如果想实现,能够应用ES6的扩大运算符...
let array=[10,20,30,40];let array1=[50,60,70,80];array.push(...array1); // 应用扩大运算符console.log(array);// 10,20,30,40,50,60,70,80
队列办法(遵循先进先出的准则)
- Array.shift(): 从数组中删除第一个元素,并返回该元素的值。此办法更改数组的长度
- Array.unshift():办法将一个或多个元素增加到数组的结尾,并返回该数组的新长度(该办法批改原有数组)
let array=[10,20,30,40];let item=array.shift();console.log(item); // 10console.log(array);// 20,30,40array.unshift(100,200,300);console.log(array);// 100,200,300,20,30,40
重排序办法
- Array.reverse():将数组中元素的地位颠倒,并返回该数组。数组的第一个元素会变成最初一个,数组的最初一个元素变成第一个。该办法会扭转原数组
- Array.sort():对数组的元素进行排序,并返回数组。默认排序程序是在将元素转换为字符串,而后比拟它们的UTF-16代码单元值序列时构建的
let array1=[10,20,30,40,50];array1.reverse();console.log(array1);// 50,40,30,20,10let array2=[10,5,20,30,40,50];array2.sort();console.log(array2);// 10,20,30,40,5,50
控制台输入能够看到,sort排序办法并没有实现咱们冀望的后果 5,10,20,30,40,50,这是因为首先sort会调用每个数组项的toString()转型办法,而后比拟失去的字符串,如果要实现冀望的后果,能够在sort中传入一个函数实现排序。
Array.sort(function(a,b){})
a:用于比拟的第一个参数
b:用于比拟的第二个参数
如果第一个参数应该位于第二个参数之前则返回一个正数,如果两个参数相等则返回0,如果第一个参数应该位于第二个参数之后则返回一个负数。
Array.sort()实现升序
let array=[10,20,40,50,30];function compare(x,y) { if(x<y){ return -1; }else if(x>y){ return 1 }else { return 0 }}array.sort(compare);console.log(array); // 10,20,30,40,50
通过排序之后,失去了排序之后升序的后果,如果想要实现降序,将地位调换一下就能够了
Arra.sort()实现降序
let array=[10,20,40,50,30];function compare(x,y) { if(x<y){ return 1; }else if(x>y){ return -1 }else { return 0 }}array.sort(compare);console.log(array); // 50,40,30,20,10
如果是对于数值类型或者其valueOf()办法会返回数值类型的对象类型,能够间接应用第一个参数减去第二个参数
操作方法
- Array.concat():用于合并两个或多个数组。此办法不会更改现有数组,而是返回一个新数组
- Array.slice([start,end]):能够承受一或两个参数,即返回项的起始地位和完结地位,只有一个参数,返回该参数指定地位到以后数组开端的所有项,如果有两个参数,该办法返回起始地位到完结地位之间的项(但不包含完结地位的项)
Array.splice():
- 删除 =>能够删除任意数量的项,只需指定两个参数,要删除第一项的地位和要删除的项数
- 插入=>能够向指定地位插入任意数量的项,只需提供3个参数,起始地位,0,要插入的项,如果要插入多个项,能够传入第n项,第n+1项,...
- 替换=>能够向指定地位插入任意数量的项,且同时删除任意数量的项,只需指定3个参数,起始地位,要删除的项数和要插入的的任意数量的项,插入的项数不用与删除的项数相等
- Array.join():应用不同的符号连贯数组
Array.concat()
let array=[10,20,30,40];let array1=[50,60];let newArray=array.concat(array1);console.log(newArray); // 10,20,30,40,50,60let array2=array.concat('20',[50,60],80);console.log(array2); // 10,20,30,40,20,50,60,80
Array.slice(start,end)
start:示意起始地位的索引
end:示意完结地位的索引
let array=[10,20,30,40,50,60,70];let array1=array.slice(1);// 没有完结地位,示意从起始地位到数组开端console.log(array1);// 20,30,40,50,60,70let array2=array.slice(2,5); // 起始地位的索引为2,完结地位的索引为5(不包含完结地位)console.log(array2);// 30,40,50
留神:如果slice()办法中起始地位或完结地位中有正数,则用数组的长度加上该数来确定,举个例子:在一个蕴含5项的数组中slice(-2,-1)和slice(3,4)是一样的,如果完结地位小于起始地位则返回空数组。
Array.splice(index,item)实现删除操作
let array=[10,20,30,40,50];array.splice(2,2); // 从索引2开始删除两项console.log(array); // 10,20,50
Array.splice(start,0,addItem)实现新增操作
let array=[10,20,30];array.splice(1,0,40,50,60);// 从下标1开始删除0项,新增40,50,60这三项console.log(array); // 10,40,50,60,20,30
Array.splice(start,deleteItem,addItem)实现批改操作
let array=[10,20,30,40,50,60,70];array.splice(2,2,90,100,110); // 从下标2开始删除2项,插入90,100,110这三项console.log(array);// 10,20,90,100,110,50,60,70
须要留神的一点是:插入项的时候是插入以后删除项的后面
Array.join()
这个办法能够应用不同的符号连接成字符串,默认不传参数应用逗号(,)进行连贯
let array=[10,20,30,40,50,60];let array1=array.join('-');let array2=array.join('|');let array3=array.joing();console.log(array1); // 10-20-30-40-50-60console.log(array2); // 10|20|30|40|50|60console.log(array3); // 10,20,30,40,50,60
地位办法
- Array.indexOf(searchElement,fromIndex):从数组的结尾(地位0)开始向后查找,没有找到返回-1
- Array.lastIndexOf(searchElemengt,fromIndex):从数组的开端开始向前查找,没有找到返回-1
searchElement:须要查找的元素
fromIndex:示意从什么地位开始查找
// 索引 0,1,2,3,4,5,6,7,8let array=[1,2,3,4,5,4,3,2,1];console.log(array.indexOf(4));// 3 查找元素为4第一次呈现的地位console.log(array.lastIndexOf(4));// 5 查找元素为4最初一次呈现的地位console.log(array.indexOf(4,4)); // 5 从索引4开始查找元素为4第一次呈现的地位console.log(array.lastIndexOf(4,4))// 3 从索引4开始查找元素为4最初一个呈现的地位
迭代办法
- Array.every(function(item,index,array)):对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则返回true
- Array.filter(function(item,index,array)):对数组中的每一项运行给定函数,返回该函数会返回true的项组成的数组
- Array.some(function(item,index,array)):对数组中的每一项运行给定函数,如果该函数对任一项返回true,则返回true
- Array.forEach(function(item,index,array)):对数组中的每一项运行给定函数,这个办法没有返回值
- Array.map(function(item,index,array)):对数组中的每一项运行给定函数,返回每次函数调用的后果返回的数组
let arrays=[1,2,3,4,5,4,3,2,1];let everyResult=arrays.every((item,index,array)=>{ return item>10;})console.log(everyResult); // falselet someResult=arrays.some((item,index,array)=>{ return item>10})console.log(someResult); // falselet filterResult=arrays.filter((item,index,array)=>{ return item>2;})console.log(filterResult); // 3,4,5,4,3let mapResult=arrays.map((item,index,array)=>{ return item*2;})console.log(mapResult);// 2,4,6,8,10,8,6,4,2arrays.forEach((item,index,array)=>{ console.log(item); // 1,2,3,4,5,4,3,2,1})
留神:以上办法都不会批改数组中蕴含的值
归并办法
- Array.reduce():迭代数组的所有项,而后构建一个最终返回的值,从数组的第一项开始,遍历到最初
- Array.reduceRight():迭代数组的所有项,而后构建一个最终返回的值,从数组的最初一项开始,向前遍历到第一项
let array=[1,2,3,4,5];let sum=array.reduce((prev,cur,index,array)=>{ return prev+cur});console.log(sum);let sum2=array.reduceRight((prev,cur,index,array)=>{ return prev+cur})console.log(sum2);
留神:reduce实现的性能有很多,这里只简略的提一下
ES6数组新增的办法
Array.from()
用于将类对象转为真正的数组,相似数组的对象和可遍历的对象,常见的类数组有:
- document.querySelectorAll('标签')获取的汇合
- 函数外部属性arguments对象
留神:只有是部署了Iterator接口的数据结构,Array.from都能将其转为数组,Array.from()办法还反对相似数组的对象,任何有length属性的对象,都能够通过Array.from办法转为数组
let lis=document.querySelectorAll('li');let arrays=Array.from(lis);arrays.push(11111);console.log(arrays);// li,li,li,11111function foo() { var args=Array.from(arguments); args.push(10,20); console.log(args); // 10,20}foo();
Array.of()
用于将一组值,转换为数组
留神:Array.of()总是返回参数值组成的数组,如果没有参数,就返回一个空数组
console.log(Array.of(3,11,8)); // 3,11,8console.log(Array.of(3)); // 3console.log(new Array(1,2)); // 1,2console.log(Array.of()); // []console.log(Array.of(undefined)); // undefinedconsole.log(Array.of(1)); // 1console.log(Array.of(1,2)); // 1,2
Array.copyWithin(target,start=0,end=this.length)
在以后数组外部,将指定地位的成员复制到其它地位(会笼罩原有成员),而后返回以后数组
参数:
target(必须):从该地位开始替换数据,如果为负值,示意倒数
start(可选):从该地位读取数据,默认为0,如果为负值,示意从开端开始计算
end(可选): 到该地位前进行读取数据,默认等于数组长度,如果为负值,示意从开端开始计算
[1, 2, 3, 4, 5].copyWithin(-2)// [1, 2, 3, 1, 2][1, 2, 3, 4, 5].copyWithin(0, 3)// [4, 5, 3, 4, 5][1, 2, 3, 4, 5].copyWithin(0, 3, 4)// [4, 2, 3, 4, 5][1, 2, 3, 4, 5].copyWithin(-2, -3, -1)// [1, 2, 3, 3, 4]
Array.fill()
应用给定值,填充一个数组
console.log(['a','b','c'].fill(7)); // 7,7,7console.log(new Array(3).fill(10)); // 10,10,10console.log(['a','b','c'].fill(7,1,2));// 'a',7,'c'
Array.find()和Array.findIndex()
- Array.find():用于找出第一个符合条件的数组成员,它的参数是一个回调函数,所有数组成员顺次执行该回调办法,直到找出第一个返回值为true的成员,而后返回该成员,如果没有符合条件的成员,则返回undefined。
- Array.findIndex():返回第一个符合条件的数组成员地位,如果所有成员都不符合条件,则返回-1
let item1=[1,4,-5,10,-6].find((n)=>n<=-5);console.log(item1); // -5let item2=[1,4,-5,10].find((item,index,arr)=>{ return item<-5})console.log(item2); // undefinedlet item3=[1,5,10,15].findIndex((item,index,arr)=>{ return item>9});console.log(item3); // 下标为2
Array.includes()
返回一个布尔值,示意某个数组是否蕴含给定的值
[1, 2, 3].includes(2); // true[1, 2, 3].includes(4); // false[1, 2, 3].includes(3, 3); // false[1, 2, 3].includes(3, -1); // true[1, 2, NaN].includes(NaN); // true
Array.flat()和Array.flatMap()
- Array.flat([depth]):用于将嵌套的数组拉平,变成一维数组,该办法返回一个新数组,对原始数据没有影响
- Array.flatMap():对原数组的每一个成员执行一个函数(相当于执行Array.map()办法),而后对返回值组成的数组执行flat办法,该办法返回一个新数组,不扭转原数组
depth:指定要提取嵌套数组的构造深度,默认值为 1
let array1=[1,2,[3,4]].flat();console.log(array1); // 1,2,3,4let array2=[1,2,[3,[4,5]]].flat();console.log(array2) // 1,2,3[,4,5]let array3=[1,2,[3,[4,5]]].flat(2);console.log(array3);// 1,2,3,4,5
#### 数组实例的entries()、keys()、values()
keys():对数组键名的遍历
values():对数组键值的遍历
entries():对数组键值对的遍历
数组其实也是有键的,个别咱们用console.log()办法输入的时候都是它的值,键示意索引,能够应用console.info()办法输入详细信息
let array=[1,2,3,4,5];for(let item of array.keys()){ console.log('键是:'+item); // 0,1,2,3,4}for(let item of array.values()){ console.log('值是:'+item); // 1,2,3,4,5}for(let [index,value] of array.entries()){ console.log(`键:${index},值:${value}`);}
数组排序的办法
数组的简略排序
上文说了一下数组自带的排序办法sort,会将数组的每一项都调用toString()办法再进行比拟,咱们先来看下一个简略的例子
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>简略排序</title> </head> <body> <script type="text/javascript"> var numbers=[4,6,8,0,1,2,3,7,9]; numbers.sort();//调用数组内置排序办法 console.log(numbers);//0,1,2,3,4,6,7,8,9 numbers.reverse();//将数组进行反转 console.log(numbers);//9,8,7,6,4,3,2,1,0 </script> </body></html>
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>简略数组自定义排序</title> </head> <body> <script type="text/javascript"> var number=[0,1,10,15,5]; function arrAsc(a,b){ //实现数组升序的办法 if(a>b){ return 1; }else if(a<b){ return -1; }else{ return 0; } } number.sort(arrAsc);//调用数组升序的办法 console.log(number);//0.1,5,10,15 function arrDesc(a,b){ //实现数组降序的办法 if(a>b){ return -1; }else if(a<b){ return 1; }else{ return 0; } } number.sort(arrDesc);//调用数组降序的办法 console.log(number);//15,10,5,1,0 </script> </body></html>
对象数组排序
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>简略对象自定义属性排序</title> </head> <body> <script type="text/javascript"> var friuts=[ { name:'apple', price:18.5, count:10 }, { name:'pear', price:1.5, count:5, }, { name:'banana', price:20.5, count:20 }, ] console.log(JSON.stringify(friuts));//未排序前 //按价格升序排序 friuts.sort(function(x,y){ return x.price-y.price; }); console.log(JSON.stringify(friuts)); //按名称排序 friuts.sort(function(x,y){ if(x.name>y.name){ return 1; }else if(x.name<y.name){ return -1; }else{ return 0; } }); console.log(JSON.stringify(friuts)); </script> </body></html>
自定义排序办法
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>通用的排序办法</title> </head> <body> <script type="text/javascript"> var friuts=[ { name:'apple', price:18.5, count:10 }, { name:'pear', price:1.5, count:5, }, { name:'banana', price:20.5, count:20 }, ] var sortExp=function(key,isAsc){ return function(x,y){ if(isNaN(key)){ if(x[key]>y[key]){ return 1*(isAsc?1:-1); }else if(x[key]<y[key]){ return -1*(isAsc?1:-1); }else{ return 0; } }else{ return (x[key]-y[key])*(isAsc?1:-1) } } } //价格升序 friuts.sort(sortExp('price',true)); console.log(JSON.stringify(friuts)); //价格降序 friuts.sort(sortExp('price',false)); console.log(JSON.stringify(friuts)); //名称升序 friuts.sort(sortExp('name',true)); console.log(JSON.stringify(friuts)); //名称降序 friuts.sort(sortExp('name',false)); console.log(JSON.stringify(friuts)); //数量升序 friuts.sort(sortExp('count',true)); console.log(JSON.stringify(friuts)); //数量降序 friuts.sort(sortExp('count',false)); console.log(JSON.stringify(friuts)); </script> </body></html>
手写数组去重的12种办法
1、应用ES6 中的Set实现去重(ES6中最罕用)
function unique (arr) { return Array.from(new Set(arr))}let array=[1,2,3,1,2,'true','true',false,false,undefined,undefined,null,null,NaN,NaN,{},{}]console.log(unique(array));// 1,2,3,'true',false,undefined,null,NaN,{},{}
毛病:能够看到{}无奈实现去重
2、应用双重for循环和splice实现去重(ES5)
function unique(array){ for(let i=0;i<array.length;i++){ // 外层循环元素 for(let j=i+1;j<array.length;j++){ // 内层进行值比拟 if(array[i]==array[j]){ array.splice(j,1); j--; } } } return array;}let array=[1,2,3,1,2,'true','true',false,false,undefined,undefined,null,null,NaN,NaN,{},{}];console.log(unique(array)); // 1,2,3,'true',false,undefined,NaN,NaN,{},{}
双层循环,外层循环元素,内层循环时比拟值。值雷同时,则删去这个值
毛病:null间接隐没,NaN和{}无奈实现去重
3、应用indexOf实现去重
function unique(arr) { let array = []; for (let i = 0; i < arr.length; i++) { if (array.indexOf(arr[i]) === -1) { array.push(arr[i]) } } return array;}let array=[1,2,3,1,2,'true','true',false,false,undefined,undefined,null,null,NaN,NaN,{},{}];console.log(unique(array));// 1,2,3,'true',false,undefined,null,NaN,NaN{},{}
毛病:NaN和{}无奈实现去重
4、应用sort()实现去重
function unique(arr) { arr = arr.sort() let array= [arr[0]]; for (let i = 1; i < arr.length; i++) { if (arr[i] !== arr[i-1]) { array.push(arr[i]); } } return array;}let array=[1,2,3,1,2,'true','true',false,false,undefined,undefined,null,null,NaN,NaN,{},{}];console.log(unique(array));// 1, 2, 3, NaN, NaN, {}, {}, false, null, "true", undefined
利用sort()排序办法,而后依据排序后的后果进行遍历及相邻元素比对。
毛病:NaN和{}无奈实现去重
5、应用对象的属性不能雷同的特点实现去重
function unique(arr) { let array= []; let obj = {}; for (var i = 0; i < arr.length; i++) { if (!obj[arr[i]]) { array.push(arr[i]) obj[arr[i]] = 1 } else { obj[arr[i]]++ } } return array;}let array=[1,2,3,1,2,'true','true',false,false,undefined,undefined,null,null,NaN,NaN,{},{}];console.log(unique(array));// 1, 2, 3, "true", false, undefined, null, NaN, {}
6、应用 includes实现去重
function unique(arr) { let array =[]; for(let i = 0; i < arr.length; i++) { if( !array.includes( arr[i]) ) { array.push(arr[i]); } } return array}let array=[1,2,3,1,2,'true','true',false,false,undefined,undefined,null,null,NaN,NaN,{},{}];console.log(unique(array));// 1, 2, 3, "true", false, undefined, null, NaN, {}, {}
毛病:{}无奈实现去重
7、应用hasOwnProperty实现去重
function unique(arr) { let obj = {}; return arr.filter(function(item, index, arr){ return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true) })}let array=[1,2,3,1,2,'true','true',false,false,undefined,undefined,null,null,NaN,NaN,{},{}];console.log(unique(array));// 1, 2, 3, "true", false, undefined, null, NaN, {}
利用hasOwnProperty 判断是否存在对象属性
8、应用filter实现去重
function unique(arr) { return arr.filter(function(item, index, arr) { return arr.indexOf(item, 0) === index; // NaN无奈实现查找 });}let array=[1,2,3,1,2,'true','true',false,false,undefined,undefined,null,null,NaN,NaN,{},{}];console.log(unique(array));// 1,2,3,'true',false,undefined,null,{},{}
毛病:NaN不见了,{}也无奈实现去重
9、应用递归实现去重
function unique(arr) { var array= arr; var len = array.length; array.sort(function(a,b){ //排序后更加不便去重 return a - b; }) function loop(index){ if(index >= 1){ if(array[index] === array[index-1]){ array.splice(index,1); } loop(index - 1); //递归loop,而后数组去重 } } loop(len-1); return array;}let array=[1,2,3,1,2,'true','true',false,false,undefined,undefined,null,null,NaN,NaN,{},{}];console.log(unique(array));// false,null,1,2,3,'true',NaN,NaN,{},{},undefined
毛病:{},NaN没有实现去重
10、应用Map数据结构实现去重
function arrayNonRepeatfy(arr) { let map = new Map(); let array = new Array(); // 数组用于返回后果 for (let i = 0; i < arr.length; i++) { if(map .has(arr[i])) { // 如果有该key值 map .set(arr[i], true); } else { map .set(arr[i], false); // 如果没有该key值 array .push(arr[i]); } } return array ;}let array=[1,2,3,1,2,'true','true',false,false,undefined,undefined,null,null,NaN,NaN,{},{}];console.log(arrayNonRepeatfy(array));// 1,2,3,'true',false,undefined,null,NaN,{},{}
创立一个空Map数据结构,遍历须要去重的数组,把数组的每一个元素作为key存到Map中。因为Map中不会呈现雷同的key值,所以最终失去的就是去重后的后果。
毛病:{}没有实现去重
11、应用reduce+includes实现去重
function unique(arr){ return arr.reduce((prev,cur) => prev.includes(cur) ? prev : [...prev,cur],[]);}let array=[1,2,3,1,2,'true','true',false,false,undefined,undefined,null,null,NaN,NaN,{},{}];console.log(unique(array));// 1,2,3,'true',false,undefined,null,NaN,{},{}
毛病:{}没有实现去重
12、应用[...new Set(arr)]实现去重
let array=[1,2,3,4,5,1,2,3,4];let newArray=[...new Set(array)];console.log(newArray); // 1,2,3,4,5
结尾
通过对本篇博客学习,置信大家对数组有更近一步的意识,如果感觉本篇博客对您有帮忙的话,记得给作者三连,点赞,关注,珍藏,您的反对就是我写作路上最大的能源,咱们下篇文章见。
参考资料
https://developer.mozilla.org...
https://segmentfault.com/a/11...
https://es6.ruanyifeng.com/#d...
JavaScript高级程序设计(第3版)