数组

一、数组介绍与创建

1、什么是数组 ,数组的特点

数组是一个引用列表,数据的组合,每个数据使用逗号分隔

特点:紧密性,按顺序排列,可以重复,数据可以是任何类型

2、数组的构成

数组由索引(下标),元素,数组长度构成

索引:数组中的数据按照顺序排列,从0开始,这个就是数组的索引,也就是下标

元素:数组中的每个数据就叫做元素

数组长度:可以理解为元素的个数,数组最大下标+1就是数组的长度

3、数组的创建

  • 字面量创建
var arr=[1,2,3];//完成数组的创建,里面有3个元素
//arr是数组,下标从0开始,arr[下标]就是数组的元素,这里arr[0]就为1
  • 构造函数创建
var arr=new Array(10);//如果只有一个参数,并且参数是正整数,这个数就是数组的长度,而不作为数组的新元素;如果是数字,但不是正整数,都会报错,如果不是数字,则作为数组的第一个元素添加
console.log(arr);//[empty*10]
var arr1=new Array(1,2,3);//不止一个参数,作为元素添加
console.log(arr1);//[1,2,3]
var arr=Array(10);//与new Array 效果一致,不同在于这是把字符串转换数组类型,而new Array是构造函数实例化对象

二、数组方法

转换为数组的方法

//ES6   Array.from(要转换的列表)
//ES5   Array.prototype.slice.call(要转换的列表)
//         [].slice.call(要转换的列表)
//      Array.prototype.concat.apply([],要转换的列表)
//      [].concat.apply([],要转换的列表)

1、push()

往数组最后位置添加一个或多个元素,返回数组的新长度,改变原数组

var arr=[1,2,3,4];
var len=arr.push(5,6);
console.log(arr,len);//[1,2,3,4,5,6],新长度6

2、pop()

删除数组最后一个元素,返回被删除的元素,改变原数组

var arr=[1,2,3,4];
var arr1=arr.pop();
console.log(arr,arr1);//[1,2,3],删除元素4

3、unshift

往数组最前面添加一个或多个元素,返回数组新长度,改变原数组

var arr=[1,2,3,4];
var len=arr.unshift(5,6);
console.log(arr,len);//[5,6,1,2,3,4],新长度6

4、shift

删除数组的第一位,返回被删除的元素,改变原数组

var arr=[1,2,3,4];
var arr1=arr.shift();
console.log(arr,arr1);//[2,3,4],删除元素1

5、sort

排序,按照ASCII码排序,二位数按照第一位排序,在sort里面写匿名函数给入参数a,b;return a-b表示升序,return b-a表示降序,改变原数组

var arr=[2,4,1,3,5,11];
arr.sort();
console.log(arr);//[1,11,2,3,4,5]
var arr1=arr.sort(function(a,b){
        return a-b;
})
console.log(arr,arr1);//[1,2,3,4,5,11],[1,2,3,4,5,11]

6、reverse

反转,可以配合sort完成倒序,改变原数组

var arr=[2,3,1,5];
var arr1=arr.reverse();
console.log(arr,arr1);//[5,1,3,2],[5,1,3,2]
var arr2=arr.sort().reverse();
console.log(arr2);//[5,3,2,1]

7、splice

给数组中插入,删除,替换一个或多个元素,返回删除的元素组成的数组,改变原数组。

三个参数splice(起始位置,删除个数,添加元素);参数可以为负数表示倒数第几位;只有一个参数表示清空数组;没有第三个元素表示删除;第二个参数为0,表示插入,1以上表示替换

//清空数组
var arr=[1,2,3,4];
var arr1=arr.splice(0);
console.log(arr,arr1);//[],[1,2,3,4]
//删除元素
var arr=[1,2,3,4];
var arr1=arr.splice(1,2);
console.log(arr,arr1);//[1,4],[2,3]
//插入元素
var arr=[1,2,3,4];
var arr1=arr.splice(1,0,5);
console.log(arr,arr1);//[1,5,2,3,4],[]
//替换元素
var arr=[1,2,3,4];
var arr1=arr.splice(1,2,5);
console.log(arr,arr1);//[1,5,4],[2,3]

上面七种方法都会改变原数组,上面七种方法都会改变原数组

8、slice

截取数组,返回截取的新数组,不会改变原数组;slice(开始截取位置,结束位置前一位),如果没有 第二个参数,默认截取到尾部,可以完成数组浅复制

var arr=[1,2,3,4];
var arr1=arr.slice(1,3);
var arr2=arr.slice(2);
var arr3=arr.slice();//复制数组
console.log(arr,arr1,arr2,arr3);//[1,2,3,4],[2,3],[3,4],[1,2,3,4]
var arr=[1,2,3,4];
var arr1=arr.slice(1,3);
var arr2=arr.slice(2);
var arr3=arr.slice();//复制数组
console.log(arr,arr1,arr2,arr3);//[1,2,3,4],[2,3],[3,4],[1,2,3,4]

9、concat

连接两个或更多数组,返回连接的数组,可以完成数组 浅复制

var arr=[1,2];
var arr1=[3,4];
var arr3=arr.concat(arr1,5,6);
console.log(arr3);//[1,2,3,4,5,6]
var arr4=arr.concat();//浅复制

10、join

返回字符串,将数组元素以指定符号连接为字符串返回出来,默认","连接

var arr=[1,2,3,4];
var str=arr.join();
var str2=arr.join(".");
console.log(str,str2);//1,2,3,4    1.2.3.4

11、indexOf lastIndexOf

查找元素,找到返回元素的下标,没找到则返回-1

indexOf 从前往后查找 lastIndexOf 从后往前查找

var arr=[1,2,3,4];
var index=arr.indexOf(2);
var index1=arr.indexOf(5);
console.log(index,index1);//下标1  -1没找到
//判断元素2在数组中出现几次
var arr=[1,2,2,3,4,2,4,5,7,8,2,10];
var index=-1;
while(~(index=arr.indexOf(2,index+1))){
    console.log(index);//1,2,5,10
}

高阶函数方法

12、forEach()

遍历数组,没有返回结果,不会遍历空元素

var arr=[1,2,3,4];
var res=arr.forEach(function(item,index,arr){
    console.log(item,index,arr);//三个参数,分别为元素,下标,遍历的数组
    return item;
});
console.log(res);//undefined  没有返回值

13、map()

遍历数组,不会遍历空元素,有返回结果,返回的是与遍历数组相同长度的新数组,里面的元素根据map回调函数的return来决定,没有return则undefined作为元素返回

var arr=[1,2,3,4];
var arr1=arr.map(function(item,index,arr){
    //三个参数,分别为元素,下标,遍历的数组
    return item*10;
})
console.log(arr1);//[10,20,30,40]

14.some()

遍历数组,不会遍历空元素,返回布尔值,如果回调函数中有一个条件满足返回true,否则返回false

var arr=[1,2,3,4];
var bool=arr.some(function(item,index,arr){
    return item>3;
})
console.log(bool);//true  有一个元素4满足条件

15.every()

遍历数组,不会遍历空元素,返回布尔值,如果回调函数中全部满足条件返回true,否则返回false

var arr=[1,2,3,4];
var bool=arr.every(function(item,index,arr){
    return item>1;
})
console.log(bool);//false  有一个元素1不满足条件

16.filter()

过滤,遍历数组,不会遍历空元素,返回新数组,将遍历数组中满足条件的元素作为新数组元素添加

var arr=[1,2,3,4];
var arr1=arr.filter(function(item,index,arr){
    return item>2;
})
console.log(arr1);//[3,4]

17、reduce()

归并 arr.reduce(function(上次归并值,本次遍历的元素,索引值,数组),初始化值);返回最终归并值

如果没有设置初始化值,上次归并值初始值为数组的第0项,本次遍历将从下标1开始

如果设置了初始化值,上次归并值初始值就是初始化值,本次遍历将从下标0开始

var arr=[1,2,3,4];
var sum=arr.reduce(function(pre,item,index,arr){
   return  pre+item;
},0);
console.log(sum);//10

18、delete

删除数组元素,不会造成数组的自动收缩,紧密,数组的长度不会发生改变

var arr=[1,2,3,4];
delete arr[2];
console.log(arr);//[1,2,empty,4]

三、数组遍历

1、for循环

使用for循环遍历数组,可以遍历到空元素

var arr=[1,2,,3];
for(var i=0;i<arr.length;i++){
    console.log(arr[i]);//1,2,undefined,3
}

2、for in循环

for in循环可以遍历到数组的可枚举属性,不能遍历空元素

var arr=[1,2,,3];
for(var prop in arr){
    console.log(arr[prop]);//1,2,3
}

3、forEach

forEach() 不遍历空元素,也不遍历属性

4、map

map不遍历空元素

四、数组去重

1、常规方法

var arr=[1,2,2,4,3,4,5,4,2,6,2,7];
var arr1=[];
for(var i=0;i<arr.length;i++){
    var bool=false;
    for(var j=0;j<arr1.length;j++){
        if(arr[i]===arr1[j]){
            bool=true;
            break;
        }
    }
    if(!bool){
        arr1.push(arr[i]);
    }
}
arr=arr1.splice(0);
arr1=null;
console.log(arr);//[1,2,4,3,5,6,7]

2、使用indexOf

var arr=[1,2,2,4,3,4,5,4,2,6,2,7];
var arr1=[];
for(var i=0;i<arr.length;i++){
    if(arr1.indexOf(arr[i])<0){
        arr1.push(arr[i]);
    }
}
arr=arr1.splice(0);
arr1=null;
console.log(arr);//[1,2,4,3,5,6,7]

3、使用delete和for in

var arr=[1,2,2,4,3,4,5,4,2,6,2,7];
for(var i=0;i<arr.length;i++){
    if(~arr.indexOf(arr[i],i+1)) delete arr[i];
}
var arr1=[];
for(var prop in arr){
    //利用for in不能遍历到数组空元素,所以空元素不会添加至arr1数组
    arr1.push(arr[prop]);
}
arr=arr1.splice(0);
arr1=null;
console.log(arr);//[1,3,5,4,6,2,7]

五、数组排序

1、冒泡排序

  • 从后向前循环
  • 内部从前向后循环到外层变量
  • 判断前前值是否大于后值,交换
var arr = [5,1,2,4,3,6];
function sort1(arr){
    var len=arr.length-1;
    while(len>0){
        for(var i=0;i<len;i++){
            if(arr[i]>arr[i+1]){
                var temp=arr[i];
                arr[i]=arr[i+1];
                arr[i+1]=temp;
            }
        }
        len--;
    }
    return arr;
}
console.log(sort1(arr));//[1,2,3,4,5,6]

2、选择排序

  • 遍历数组
  • 设置最新的索引值为当前的索引值
  • 从当前的下一项开始遍历到数组的尾部
  • 判断所有遍历的值中最小的值的索引值
  • 交换当前值和最小索引值的元素
var arr = [5,1,2,4,3,6];
function sort2(arr){
    var minIndex;
    for(var i=0;i<arr.length-1;i++){
        minIndex=i;
        for(var j=i+1;j<arr.length;j++){
            minIndex=arr[minIndex]<arr[j] ? minIndex : j;
        }
        var temp=arr[i];
        arr[i]=arr[minIndex];
        arr[minIndex]=temp;
    }
    return arr;
}
console.log(sort2(arr));//[1,2,3,4,5,6]
  • 3、快速排序
  • 删除数组中间的元素,并且将这个元素返回一个变量
  • 创建两个空数组,一个是left,一个是right,遍历这个数组,将小于中间元素的数据存入left,大于中间元素的数据存入right
  • 将left数组递归与中间元素和right数组递归的结果合并返回
  • 在函数最顶部,一定要写数组长度小于等于1返回该数组
  • 得到的数组重新赋值给原数组
var arr = [5,1,2,4,3,6];
function sort3(arr){
    if(arr.length<=1) return arr;
    var item=arr.splice(parseInt(arr.length/2),1)[0];
    var left=[],right=[];
    for(var i=0;i<arr.length;i++){
        if(arr[i]<item) left.push(arr[i]);
        else right.push(arr[i]);
    }
    return sort3(left).concat(item,sort3(right));
}
var arr=sort3(arr);
console.log(arr);//[1,2,3,4,5,6]