Administrator
发布于 2020-07-24 / 13036 阅读 / 0 评论 / 6 点赞

数组

数组

数组是大多数编程语言都里面都会有的东西,不同类型的编程语言对数组的概念定义是一样的

  • 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

image-20200721093515488

数组的检测

数组在检测的时候,如果我们使用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数组与其它语言数组的区别

  1. JavaScript里面的数组下标可以越界访问,但是其它语言的数组是不可以的
  2. JavaScript里面的数组的长度由所出现的最大索引来决定,而其它语言里面的数组是由长度决定最大索引
  3. JavaScript里面的数组没有限制数据类型,而其它语言里面的数组必须是相同事的数据类型

数组的简单遍历

遍历指的是将数组里面的每一个元素都拿出来,走一遍

var stus = ["小雨", "小夫", "小奥", "胖虎", "静香","帅哥"];

如果要将上面的数组每个元素都打印一遍,这个时候我们就要使用数组遍历的技巧

for(var i=0;i<stus.length;i++){
    console.log(stus[i]);
}

这个时候的i从0开始,也就是数组的第1个元素,到i<stus.length结束,也就是到数组的最后一个索引(最后一个元素)。这样通过stus[i]每个元素都会访问到

数组的属性与方法

属性:用于描述事物的特征的我们叫属性

方法:在面向对象的概念里面,方法就是之前所学习的函数,

学习数组里面的属性与方法可以让我们更方便的了解数组,操作数组

  1. length属性,该属性用于获取数组长度或设置数组的长度

    var arr = new Array(5);
    console.log(arr.length);		//得到长度5
    arr.length = 10;				//重新设置当前数组的长度为10
    
  2. push(...items:any[]):number方法,向当前数组的最后面去添加元素,并返回当前数组的长度

    var arr = ["小奥","小雨"];
    var x = arr.push("小夫");				
    //这个时候的数组arr会变为["小奥","小雨","小夫"]; x则是返回的数组长度为3
    
    //数组在push的时候可以同时添加多个元素
    arr.push("何陈龙","吴港");
    
  3. pop()方法,从当前数组的最后移除一个元素,并返回这个移除的元素

    var arr = ["吴紫婷", "颜若瑄", "刘雪年", "程紫圆"];
    var x = arr.pop();	
    //这个时候的数组变为["吴紫婷", "颜若瑄", "刘雪年"]; x就是返回的移除的元素“程紫圆”
    
  4. unshift(...items:any[]):number方法,向当前数组的最前面添加元素,并返回当前数组的长度

    var arr = ["吴紫婷", "颜若瑄", "刘雪年", "程紫圆"];
    var x = arr.unshift("杨兰芳", "梁心悦");
    //这个时候数组变为["杨兰芳", "梁心悦","吴紫婷", "颜若瑄", "刘雪年", "程紫圆"]
    //x代表当前数组的长度为6
    
  5. shift()方法,从当前数组的前面去移除第一个元素,并返回这个移除的元素

    var arr = ["吴紫婷", "颜若瑄", "刘雪年", "程紫圆"];
    var x = arr.shift();
    //这个时候的arr变成["颜若瑄", "刘雪年", "程紫圆"]
    //x就是移除的第一个元素“吴紫婷”
    
  6. 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就互不影响
    
  7. 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");       //["吴港", "何陈龙", "小雨"]
    
  8. reverse():Array方法,该方法将数组里面的元素反转,返回一个新的数组,原数组也改变

    var arr = ["a","b","c","d","e"];
    var arr1 = arr.reverse();
    //这个地方的原数组arr与新数组arr1都会变成["e", "d", "c", "b", "a"],新旧数组其实在内在当中是同一个数组
    
  9. toString()方法,将数组里面的元素用逗号隔开以后变成一个字符串

    var arr1 =["杨标", "吴港", "何陈龙"];
    var str = arr1.toString();          //"杨标,吴港,何陈龙"
    
  10. join(separator?: string):string方法,将数组里面的元素用指定的字符隔开,然后转成字符串

    如果没有指定隔开的符号,则会默认使用逗号进行隔开,这个时候与toString()的效果是一样的

    var arr1 =["杨标", "吴港", "何陈龙"];
    var str = arr1.join("-");           //"杨标-吴港-何陈龙"
    var str2 = arr1.join("#");			//"杨标#吴港#何陈龙"
    var str3 = arr.join();				//"杨标,吴港,何陈龙"
    
  11. 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
    
  12. 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
    
  13. 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个方法

所有的迭代方法都有以下几个特点

  1. 不能使用break以及continue关键字来中断遍历迭代
  2. 所有的遍历都是静态遍历,在遍历最开始的时候就已经确定了要遍历多少次,这个次数只小于或等于原来的数组长度

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方法

该方法会对数组里面的每个元素执行遍历,回调函数返回一个条件,它根据这个条件来决定返回结果是truefalse,并且最后它执行的是的操作

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

案例与练习

  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);
    
  2. 现有一数组,找数这个数组里面最大的奇数值与偶数值

    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);
    
  3. 现有一数组,里面的元素如下

    var arr = [1,4,7,11,23,45,32,29,9,54];
    

    请求出上面数组里面的奇数的和与偶数的和分别是多少

  4. 现有一数组,元素如下

    var arr = [1,4,7,11,23,45,32,29,9,54];
    

    请编写程序删除里面的奇数的值的项

  5. 给一个数组,元素如下

    var arr = [1,4,7,11,23,45,32,29,9,54];
    

    请编写方法,找出这个数组中最大的一个数,然后将这个数放到一个新的数组里面,再到原来的数组里面删队这个数,依次执行, 直到原数组为空,这样新数组得到的结果就是一个从大到小的结果

  6. 现有一数组,元素如下【数组去重】

    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"];
    
  7. 现有如下两个数组,找出两个数组当中相同的元素,放在一个新的数组里面

    var arr1 = [1,2,7,4,3,"a","d","g"];
    var arr2 = [7,3,"d","g","h",3,7];
    
  8. 现有一个数组,里面有几个重复的元素,找出重复次数最多的元素,并列出每个元素重复多少次

    var arr= ["a","b","c","a","a","b","d","e","f","c","g","d","e","g","a","c","a" ,"h","a"];
    

评论