数组
数组是大多数编程语言都里面都会有的东西,不同类型的编程语言对数组的概念定义是一样的
- JavaScript里面的数组概念:一系列数据的集合
- 其它强类型语言里面数组的概念:一系列相同数据类型的固定长度的数据集合
数组的定义
数组的定义也叫数组的创建,它有多种方式来进行创建
通过new Array()
的方式来定义
第一种方式:直接通过new Array()
最原始的方式来创建
var arr = new Array();
//这样就创建了一个空的数组,这个数组里面什么值都没有,数组的长度为0
这里面有一个new的关键字,这个关键到后面讲到构造函数会跟大家讲(对象的章节)
new Array()则代表创建一个Array的实例
第二种方式:创建数组的时候,直接定义数组的长度new Array(arrayLength?:Number):[]
var arr = new Array(6);
//这样就创建了一个数组,这个数组的长度为6
第三种方式:直接静态初始化
数组是存放一系列数据的集合,我在创建这个数组的时候,我就直接把数据都放进去
var arr3 = new Array(1, 2, 3, 4, 5, 6, 7);
var arr4 = new Array("A",123,true,undefined,"hello",NaN);
在这三种定义的过程当中,请同学们尤其要注意第2种与第3种的区别
如果在使用第2种或第3种方式在定义的时候,里面是可以放参数的,如果只有一个参数,并且这个参数是数字类型,则代表定义的时候是设置了数组的长度,不代表里面的具体值
? 注意如下的问题
var a = new Array("2"); //"2"代表里面的元素,因为是字符串类型
var b = new Array(2); //2代表数组的长度为2,因为是数字类型
var c = new Array(-1); //这样会报错
var d = new Array(3.5); //这样会报错
var e = new Array(-1,-2); //静态初始化
通过[]
的方式来定义数组
在上面的代码里面,我们已经看到我们可以通过new Array()
来创建数组,同时我们也知道了new Array()
得到的结果就是一对空的中括号,所以我们定义数组的时候可以直接使用[]
来定义,后期我也希望各位同学优先使用这种方式
var a = []; //定义了一个空的数组
var b = [1,2,true,null,"hello",NaN]; //这就是静态初始化
var c = [-1]; //这也是一个静态初始化,数组的第一个值是-1
数组的检测
数组在检测的时候,如果我们使用typeof
去检测,这个时候会得到什么类型呢?
var arr = [1,2,3];
typeof arr; //"object"
我们可以看到通过typeof
关键字去检测的时候,得到的结果是object
。这样不行,因为有很多类型检测出来的结果都是object
var d = new Date();
typeof d ; //"object"
var e = new String("123");
typeof e ; //"object"
这个时候我们发现,我们用typeof
关键字去检测的时候,得到的结果都是object
并不能严格的区分它们的数据类型 ,所以怎么办呢?
注意:typeof
关键字只适用于做基本数据类型检测,对于object
的结果,则说明它是一个复杂的数据类型,我们就不能够使用这个关键字。对于复杂的数据类型检测,我们要使用另一个关键字instanceof
通过instanceof
关键字来检测
数组是通过new Array()
得出来的,所以每个数组应该都是Array
的实例
var a = [1,2,3];
var b = new Array();
a instanceof Array; //判断a是否是Array的实例,就相当于判断a是否是由Array new 出来的
b instanceof Array; //得到的结果为true
只要是通过instanceof Array
得到的结果为true就有可能说明它是一个数组。通过这一点我们还可以引得出其它的数据类型检测
var a = new Array();
var d = new Date();
现在我们分另对上面的a与b做复杂数据类型检测
a instanceof Array; //true
a instanceof Date; //false
d instanceof Array; //false
d instanceof Date; //true
通过Array.isArray()
来判断
这是数组里面提供的一个方法,专门用于检测一个变量是否是一个数组
var a = new Array();
var d = new Date();
Array.isArray(a); //true 说明是一个数组
Array.isArray(d); //false 说明不是一个数组
?为什么要检测数组?
如果某一个变量它已经是数组了,那么我们就可以按照组的操作方式去操作它
数组的取值与赋值
我们将一系列的数据放到一个数组里面去了以后,怎么取值呢?
数组的取值与赋值是通过下标(索引)来完成的,索引从0开始,通过数组名[下标]
这种方式来完成取值与赋值。数组里面的值也叫数组里面的元素
var stus = ["张三", "小夫", "小奥", "胖虎", "静香"];
//取值
var a = stus[2]; //小奥
stus[0]="小雨"; //将小雨赋值给数组的第0个数
var b = stus[5]; //不会报错,会得到undefined,但是在强类型C/Java等语言会报
stus[10] = "何陈龙"; //不会报错,数组的长度会变成11
stus[4] = 18; //数组没有限定数据类型 ,所以它不会报错
JavaScript数组与其它语言数组的区别
- JavaScript里面的数组下标可以越界访问,但是其它语言的数组是不可以的
- JavaScript里面的数组的长度由所出现的最大索引来决定,而其它语言里面的数组是由长度决定最大索引
- JavaScript里面的数组没有限制数据类型,而其它语言里面的数组必须是相同事的数据类型
数组的简单遍历
遍历指的是将数组里面的每一个元素都拿出来,走一遍
var stus = ["小雨", "小夫", "小奥", "胖虎", "静香","帅哥"];
如果要将上面的数组每个元素都打印一遍,这个时候我们就要使用数组遍历的技巧
for(var i=0;i<stus.length;i++){
console.log(stus[i]);
}
这个时候的i从0开始,也就是数组的第1个元素,到i<stus.length
结束,也就是到数组的最后一个索引(最后一个元素)。这样通过stus[i]
每个元素都会访问到
数组的属性与方法
属性:用于描述事物的特征的我们叫属性
方法:在面向对象的概念里面,方法就是之前所学习的函数,
学习数组里面的属性与方法可以让我们更方便的了解数组,操作数组
-
length
属性,该属性用于获取数组长度或设置数组的长度var arr = new Array(5); console.log(arr.length); //得到长度5 arr.length = 10; //重新设置当前数组的长度为10
-
push(...items:any[]):number
方法,向当前数组的最后面去添加元素,并返回当前数组的长度var arr = ["小奥","小雨"]; var x = arr.push("小夫"); //这个时候的数组arr会变为["小奥","小雨","小夫"]; x则是返回的数组长度为3 //数组在push的时候可以同时添加多个元素 arr.push("何陈龙","吴港");
-
pop()
方法,从当前数组的最后移除一个元素,并返回这个移除的元素var arr = ["吴紫婷", "颜若瑄", "刘雪年", "程紫圆"]; var x = arr.pop(); //这个时候的数组变为["吴紫婷", "颜若瑄", "刘雪年"]; x就是返回的移除的元素“程紫圆”
-
unshift(...items:any[]):number
方法,向当前数组的最前面添加元素,并返回当前数组的长度var arr = ["吴紫婷", "颜若瑄", "刘雪年", "程紫圆"]; var x = arr.unshift("杨兰芳", "梁心悦"); //这个时候数组变为["杨兰芳", "梁心悦","吴紫婷", "颜若瑄", "刘雪年", "程紫圆"] //x代表当前数组的长度为6
-
shift()
方法,从当前数组的前面去移除第一个元素,并返回这个移除的元素var arr = ["吴紫婷", "颜若瑄", "刘雪年", "程紫圆"]; var x = arr.shift(); //这个时候的arr变成["颜若瑄", "刘雪年", "程紫圆"] //x就是移除的第一个元素“吴紫婷”
-
concat()
方向,将多个数组拼接成一个新的数组,返回这个新的数组,原数组不变var arr1 = ["梁心悦", "杨兰芳"]; var arr2 = ["小奥", "小雨", "小夫"]; var arr4 = ["陈红", "李洁平"] var arr3 = arr1.concat(arr2, arr4); //这个时候的arr1,arr2,arr3分别是什么 //arr3 :["梁心悦", "杨兰芳","小奥", "小雨", "小夫","陈红", "李洁平"] //arr1,arr2,arr4的原数组并没有发生改变
上面的数组的拼接还可以使用下面的语法来完成
/* var temp = arr1.concat(arr2); //["梁心悦", "杨兰芳","小奥", "小雨", "小夫"] var arr3 = temp.concat(arr4); //["梁心悦", "杨兰芳","小奥", "小雨", "小夫","陈红", "李洁平"] */ var arr3 = arr1.concat(arr2).concat(arr4); //["梁心悦", "杨兰芳","小奥", "小雨", "小夫","陈红", "李洁平"]
小技巧:我们目前阶段可以通过下面的方式复制一份数组
var arr1 = ["梁心悦", "杨兰芳"]; var arr2 = arr1.concat(); //这个时候arr1就与arr2里面的的元素的值相同 //arr1与arr2就互不影响
-
slice(start?: number, end?: number):Array
方向,截取数组当中的元素,返回一个新的数组,原数组不变start代表开始索引,end代表结束索引(但是不包含结束索引)
var arr1 = ["杨标", "吴港", "何陈龙", "小雨", "小奥","小夫"]; var arr2 = arr1.slice(1,4); //arr2得到的结果["吴港", "何陈龙", "小雨"] var arr3 = arr1.slice(1); //arr3得到的结果["吴港", "何陈龙", "小雨", "小奥","小夫"] //省略了结束索引,所以是从索引1开始,一直到最后一个 var arr4 = arr1.slice(); //arr4得到的结果["杨标", "吴港", "何陈龙", "小雨", "小奥","小夫"] //省略了开始索引与结束索引,相当于复制一份相同事的数组,两人数组互不影响 var arr5 = arr1.slice(1,-1); //arr5得到的结果["吴港", "何陈龙", "小雨", "小奥"] //-1相当于倒数第1个 var arr6 = arr1.slice(-3,-1); //arr6得到的结果["小雨", "小奥"] //理解为从倒数第3个截到倒数第1个
下面的几种特殊情况也要了解一下
var arr7 = arr1.slice(4,1); //arr7得到的结果[],因为开始索引的位置不能大于结束索引的位置 var arr8 = arr1.slice(1,"a"); //[] var arr9 = arr1.slice(1,"4"); //["吴港", "何陈龙", "小雨"]
-
reverse():Array
方法,该方法将数组里面的元素反转,返回一个新的数组,原数组也改变var arr = ["a","b","c","d","e"]; var arr1 = arr.reverse(); //这个地方的原数组arr与新数组arr1都会变成["e", "d", "c", "b", "a"],新旧数组其实在内在当中是同一个数组
-
toString()
方法,将数组里面的元素用逗号隔开以后变成一个字符串var arr1 =["杨标", "吴港", "何陈龙"]; var str = arr1.toString(); //"杨标,吴港,何陈龙"
-
join(separator?: string):string
方法,将数组里面的元素用指定的字符隔开,然后转成字符串如果没有指定隔开的符号,则会默认使用逗号进行隔开,这个时候与
toString()
的效果是一样的var arr1 =["杨标", "吴港", "何陈龙"]; var str = arr1.join("-"); //"杨标-吴港-何陈龙" var str2 = arr1.join("#"); //"杨标#吴港#何陈龙" var str3 = arr.join(); //"杨标,吴港,何陈龙"
-
splice(start: number, deleteCount: number, ...items: string[]):Array
方法在指定位置,删除指定个数的元素,放入指定个数的新元素,然后再将删除的元素组成一个新的数组返回
start代表开始的索引,可以为负数
deleteCount代表删除元素的个数,不能是负数,如果不是number类型,则调用
Number()
转一次var arr1 =["杨标", "吴港", "何陈龙","小夫"]; //第一种情况 var arr2 = arr1.splice(1,2); //从索引为1的位置删除2个元素 arr1结果["杨标","小夫"], //arr2则是删除的元素组成的新数组["吴港", "何陈龙"] //第二种情况 var arr3 = arr1.splice(1,0,"程紫圆","颜若瑄"); //arr1的结果["杨标", "程紫圆","颜若瑄","吴港", "何陈龙","小夫"]; //第三种情况 var arr4 = arr1.splice(1,1,"小奥","晓祺"); //arr1的结果["杨标","小奥","晓祺" , "何陈龙","小夫"]; //从索引为1的位置,删除1个,新增后面2个
特殊情况
arr1.splice(1); //从索引为1的位置开始,一直删除到最后一个 arr1.splice(-2); //从倒数第2的位置开始,一直删除到最后一个 arr1.splice(1,-1); //数组保持不变 arr1.splice(1,"a"); //数组保持不变 arr1.splice(1,"1"); //把字符串“1”转换成数字1
-
indexOf(searchElement: string | number | boolean, fromIndex?: number)
方法,查找某一个元素在数组当中的位置,返回这个元素的索引,如果没有找到,则返回-1
indexOf在查找的时候执行的是全等操作,强判断
searchElement代表查找的元素,只查询基本数据类型string ,number ,boolean
fromIndex代表从第几个位置开始查找
var arr1 = ["a", "b", "c", "11", "true", 11, true, "f"]; var x = arr1.indexOf("c"); //2 var y = arr1.indexOf(11); //5 执行是全等操作强判断 var z = arr1.indexOf(false); //-1
在查找的时候,如果发现里面有多个元素,则永远都只会查找到第1个
var arr2 = ["a","b","a","c","b",11,"true",false]; var x1 = arr2.indexOf("b"); //1 只返回第一次找到的值
特殊情况:indexOf在查找元素位置的时候,还可以指定从某个位置开始查找。如下:
var arr2 = [123, 456, "a", "b", "a", "c", "b", 11, "true", "a", false]; var x = arr2.indexOf("a", 4); //4 var y = arr2.indexOf("a",5); //9 var z = arr2.indexOf("b",8); //-1
-
lastIndexOf(searchElement: string | number | boolean, fromIndex?: number)
查找某一个元素在数组当中最后一次出现的位置,返回这个位置的索引,如果找不到则返回-1
lastIndexOf
与上面的indexOf
非常相似,在查找的时候都是执行全等操作,强判断这里的
fromIndex
我们要把它理解成endIndex
var arr2 = [123, 456, "a", "b", "a", "c", "b", 11, "true", "a", false]; var x = arr2.lastIndexOf("a"); //9 var y = arr2.lastIndexOf("c"); //5 var z = arr2.lastIndexOf("a", 5); //4
上面的数组的方法我们可以分为下面这几类
数组的迭代方式
数组的迭代方法也叫数组的遍历方法,它有5个方法,我们现来学习一下这5个方法
所有的迭代方法都有以下几个特点
- 不能使用
break
以及continue
关键字来中断遍历迭代 - 所有的遍历都是静态遍历,在遍历最开始的时候就已经确定了要遍历多少次,这个次数只小于或等于原来的数组长度
forEach方法
它是一个纯粹的遍历方法,它会将数组中的每一个元素都遍历出来,然后交给我们
var arr = ["a", "c", "b", "f", "h", "g", "e"];
for (var i = 0; i < arr.length; i++) {
//console.log(arr[i], i);
abc(arr[i], i);
}
function abc(item, index) {
console.log(item,index);
}
上面代码是一种最原始的遍历方式,在这里我们可以看到abc这个方法只负责打印,for这个语句就只负责遍历
var arr = ["a", "c", "b", "f", "h", "g", "e"];
arr.forEach(function (item, index, _arr) {
console.log(item + "-------" + index);
});
上面的代码就使用了
forEach
遍历的方法,它使用回调函数完成后续的操作,回调函数里面接收三个参数
item
代表当前遍历的这一项index
代表当前遍历的这一项的索引_arr
代表当前正在遍历的数组
map方法
它也是一个迭代方法,它与forEach非常相似,唯一的不同点就可以将每一次迭代的回调函数的返回值接收下来,然后组成一个新的数组,返回出去
var arr = [11, 23, 67, 43, 54, 98, 6];
var newArr = arr.map(function (item, index, _arr) {
console.log(item + "-------" + index);
var x = item * 2;
return x;
});
//newArr的结果为[22, 46, 134, 86, 108, 196, 12]
这个时候得到的newArr
就是每次回调函数的返回值组成的一个新数组
filter方法
该方法与map方法非常相似,它会在原数组里面返回符合指定条件的元素,然后将这些元素组成数组返回到外边
var arr = [11, 23, 67, 43, 54, 98, 6];
var even_arr = arr.filter(function (item, index, _arr) {
// 这里返回的是一个条件,然后原数组会根据这一个条件返回符合条件的值
return item % 2 === 0;
});
通过这个方法我们还可以让数组快速的去重
var arr = [1, 2, 7, 4, 2, 4, "a", "b", "f", "a", "c", "f"];
var noRepeatArr = arr.filter(function (item, index, _arr) {
return index == _arr.indexOf(item);
});
every方法
该方法会对数组里面的每个元素执行遍历,回调函数返回一个条件,它根据这个条件来决定返回结果是
true
或false
,并且最后它执行的是与
的操作
var arr = [11, 23, 44, 38, 67, 43, 54, 98, 6, 22, 56, 45, 77, 18];
//判断上面是否每个数都大于10
//[true,true,true,true,true,true,true,true,false,true,true,true,true,true]
var result = arr.every(function (item, index, _arr) {
return item > 10
});
some方法
该方法参照
every
方法,只是在最后执行的是或运算
var arr = [11, 23, 44, 38, 67, 43, 54, 98, 6, 22, 56, 45, 77, 18];
//判断上面的元素是否有大于90的数
var result = arr.some(function (item, index, _arr) {
return item > 90;
});
数组的归并方法
reduce
方法
它的语法格式如下
var result = arr.reduce(function(prev,current,index,_arr){
//代码
});
prev
代表前一个的回调函数的返回值【这一次回调函数的返回值会作为下一次回调函数当中的prev
使用】current
代表当前遍历的这一次的值【reduce
是从数组的第二项元素开始的】index
代表当前遍历的索引_arr
代表当前正在操作的这个数组result
代表最后一次回调函数的返回值
场景一:通过reduce求数组的和
var arr = [8, 7, 6, 3, 2, 10, 1, 4, 5, 9];
var result = arr.reduce(function (prev, current, index, _arr) {
console.log("前:" + prev + "----当前:" + current);
var sum = prev + current;
return sum;
});
场景二:通过reduce求数组最大的元素
var arr = [8, 7, 6, 3, 2, 10, 1, 4, 5, 9];
var result = arr.reduce(function (prev, current, index, _arr) {
var max = prev > current ? prev : current;
return max;
});
reduceRight
方法
这个方法与上面的reduce
方法一样,只是从右边开始遍历
排序方法
在数组里面,数组提供了一个让数组排序的方法,这个方法就是sort
sort()
会将当前数组进行排序,同时会返回一个新的数组,新旧数组其实是同一个数组
var arr = [8, 7, 6, 3, 2, 1, 4, 10, 5, 9];
//arr.sort(); [1, 10, 2, 3, 4, 5, 6, 7, 8, 9] 明显是不符合要求
//让sort这个排序的方法按照指定的回调函数的规则来进行
arr.sort(function (a, b) {
if (a < b) {
return -1;
} else if (a == b) {
return 0; //0代表两个元素不换位置
} else if (a > b) {
return 1;
}
});
//如果想第1个值在第2个值的后面,我们返回1
//如果想第1个值在第2值的前面,我们返回-1
案例与练习
-
现有下几的数组,请求出数组当中最大的一个值
var arr = [18,23,9,11,76,23,97,55,33];
思路,我先假设第一个元素是最大的,然后让后面的每个元素都跟这个元素比较,如果这个元素没有后面元素到,就把后面这个元素变成最大值,然后继续比较
var arr = [18, 23, 9, 11, 76, 23, 97, 55, 33]; //第一步:先假设第0个元素是最大值 var max = arr[0]; //接下来让后面的每个元素都比一比 for (var i = 1; i < arr.length; i++) { // if (max < arr[i]) { // max = arr[i]; // } max = max < arr[i] ? arr[i] : max; } console.log(max);
-
现有一数组,找数这个数组里面最大的奇数值与偶数值
var nums = [124, 67, 89, 345, 96, 354, 456, 233]; var max_even; //偶数 var max_odd; //奇数 //第一步:先随便找个偶数 for (var i = 0; i < nums.length; i++) { if (nums[i] % 2 == 0) { max_even = nums[i]; break; } } //第二步:先随便找个奇数 for (var i = 0; i < nums.length; i++) { if (nums[i] % 2 != 0) { max_odd = nums[i]; break; } } //第三步:比武招亲 for (var i = 0; i < nums.length; i++) { if (nums[i] % 2 == 0) { //偶数 if (nums[i] > max_even) { max_even = nums[i]; } } else { //奇数 if (nums[i] > max_odd) { max_odd = nums[i]; } } } console.log(max_even, max_odd);
-
现有一数组,里面的元素如下
var arr = [1,4,7,11,23,45,32,29,9,54];
请求出上面数组里面的奇数的和与偶数的和分别是多少
-
现有一数组,元素如下
var arr = [1,4,7,11,23,45,32,29,9,54];
请编写程序删除里面的奇数的值的项
-
给一个数组,元素如下
var arr = [1,4,7,11,23,45,32,29,9,54];
请编写方法,找出这个数组中最大的一个数,然后将这个数放到一个新的数组里面,再到原来的数组里面删队这个数,依次执行, 直到原数组为空,这样新数组得到的结果就是一个从大到小的结果
-
现有一数组,元素如下【数组去重】
var arr = [1,2,7,4,2,4,"a","a","b","f","a","c","f"]
请编写程序去除数组中相同的的元素。这个时候得到的结果应该是
var newArr = [1,2,7,4,"a","b","f","c"];
-
现有如下两个数组,找出两个数组当中相同的元素,放在一个新的数组里面
var arr1 = [1,2,7,4,3,"a","d","g"]; var arr2 = [7,3,"d","g","h",3,7];
-
现有一个数组,里面有几个重复的元素,找出重复次数最多的元素,并列出每个元素重复多少次
var arr= ["a","b","c","a","a","b","d","e","f","c","g","d","e","g","a","c","a" ,"h","a"];