zoukankan      html  css  js  c++  java
  • 【原】javascript数组操作

    继续我的第二遍《javascript高级程序设计第三版》,今天要做的笔记是array

    一、数组的操作

    1、数组的创建:

    var colors= new Array(); //创建一个数组
    
    var colors = new Array(20); //创建一个数组并指定长度
    
    var colors = new Array("red","blue","green"); //创建一个数组并赋值
    

    airbnb的规范建议,我们在创建数组的时候,最好采用省略new操作符的形式,如下:

    airbnb网址:https://github.com/airbnb/javascript

    // bad
    var items = new Array();
     
    // good
    var items = [];

    2、数组的元素的访问

    var colors=["red","blue","green"]
    
    alert(colors[0]); //显示第一项
    
    colors[2]="black";  //修改第三项
    
    colors[3]="brown"; //新增第四项
    

    1、通过方括号加索引值访问

    2、设置在索引值在范围内的其他值,可以替换指定位置的值

    3、如果索引值超过了数组现有的项数,数组会自动增加到该索引值加1的长度,如代码中的新增第四项

    3、数组中添加元素:

    有以下几种方法:

    1、push,将元素添加到数组的末尾:

    var colors=[];
    colors.push("red","blue");
    console.log(colors);  //[red,blue]

    2、索引值超过了数组现有的项数来添加。因为索引值是从0算起的,所以数组的长度总比索引值大1

    var colors=["red","blue","green"];
    
    colors[colors.length]="black";
    
    console.log(colors);  //["red","blue","green","black"];

    3、unshift,将元素添加到数组的前端

    var colors=["red","blue","green"];
    
    colors.unshift("black");
    
    console.log(colors);  //["black","red","blue","green"];
    

      

    4、splice ,可以指定位置插入任意数组的项。至少需要三个参数:起始位置,0和要插入的项.当然也可以插入多项。

    var arr = ["George","John","Thomas","James","Adrew","Martin"];
    
    arr.splice(2,0,"William")
    
    console.log(arr);  //["George","John","William","Thomas","James","Adrew","Martin"];

    4、数组的删除、替换

    数组的删除:

    1、arrayObj.pop(); //移除最后一个元素并返回该元素值

    2、arrayObj.shift(); //移除最前一个元素并返回该元素值,数组中元素自动前移

    3、arrayObj.splice(start,length); //删除从指定位置start开始的指定数量length的元素,数组形式返回所移除的元素

    4、指定数组的length小于它的长度

    var arr = ["George","John","William","Thomas","James","Adrew","Martin"];
    
    var deleteItem1=arr.pop(); 
    console.log(deleteItem1);  //Martin
    console.log(arr);  //["George", "John", "William", "Thomas", "James", "Adrew"]
    
    var deleteItem2=arr.shift(); 
    console.log(deleteItem2);  //George
    console.log(arr);   //["John", "William", "Thomas", "James", "Adrew"]
    
    var deleteItem3=arr.splice(0,2); 
    console.log(deleteItem3);  //["John", "William"]
    console.log(arr);          //["Thomas", "James", "Adrew"]
    
    arr.length=2;
    console.log(arr);  ////["Thomas", "James"]

      

    数组的替换:

    array.splice(start,length,"otherValue")  传三个值,开始替换位置,替换的数量,替换后的值。

    var arr = ["George","John","William","Thomas","James","Adrew","Martin"];
    
    var arr2 = ["George","John","William","Thomas","James","Adrew","Martin"];
    
    
    
    var deleteItem=arr.splice(0,1,"123");  //返回被替换的值
    console.log(deleteItem); //["George"]
    console.log(arr);  // ["123", "William", "Thomas", "James", "Adrew", "Martin"]
    
    var deleteItem2=arr2.splice(0,2,"123","456");  //返回被替换的值.可以替换多个值
    console.log(deleteItem2); //["George", "John"]
    console.log(arr2);  // ["123", "456", "William", "Thomas", "James", "Adrew", "Martin"]
    

    5、数组的截取、合并和复制

    1、截取数组:slice(start,end)   

      以数组的形式返回被截取部分。不包括end对应的项。

      如果省略end,则截取start之后的所有元素。

      只传0,相当于复制了数组

      

    var arr = ["George","John","William","Thomas","James","Adrew","Martin"];
    
    var getArray=arr.slice(1,3);
    console.log(getArray); //["John", "William"]
    console.log(arr);    //["George", "John", "William", "Thomas", "James", "Adrew", "Martin"]  不影响原数组
    
    var getArray2=arr.slice(1);
    console.log(getArray2);  //["John", "William", "Thomas", "James", "Adrew", "Martin"]
    
    console.log(arr.slice(0)); //["George","John","William","Thomas","James","Adrew","Martin"]
    

    2、数组的合并:arrayObj.concat([item1[, item2[, . . . [,itemN]]]]); 

     将多个数组(也可以是字符串,或者是数组和字符串的混合)连接为一个数组,返回连接好的新的数组。

      如果什么也不传,相当于复制数组。

    var arr = ["George","John","William","Thomas","James","Adrew","Martin"];
    
    var arr2=["123","456"];
    
    var arr3=arr.concat(arr2);
    
    console.log(arr3); //["George", "John", "William", "Thomas", "James", "Adrew", "Martin", "123", "456"]
    

     

     

    6、数组的字符创化: array.join();

    返回字符串,这个字符串将数组的每一个元素值连接在一起,中间用传入的值隔开。

    var arr = ["George","John","William","Thomas","James","Adrew","Martin"];
    
    console.log(arr.join(','));  //George,John,William,Thomas,James,Adrew,Martin
    console.log(arr.join('-')); //George-John-William-Thomas-James-Adrew-Martin
    console.log(arr.join(' ')); //George John William Thomas James Adrew Martin
    

     

    7、数组的排序:reverse()反序    sort()正序

    var arr = [1,5,8,9,6,3];
    
    console.log(arr.reverse());   //[3, 6, 9, 8, 5, 1]
    console.log(arr.sort());  //[1, 3, 5, 6, 8, 9]
    console.log(arr.sort().reverse()); //[9, 8, 6, 5, 3, 1]
    

      

     

    二、数组的高级用法

     1、栈方法和队列:

    栈方法:

    栈是一种 LIFO(Last-In-First-Out,后进先出)的数据结构,也就是最新添加的项最早被移除。而栈中项的插入(叫做推入)和移除(叫做弹出) ,只发生在一个位置——栈的顶部。

    ECMAScript 为数组专门提供了 push() 和 pop() 方法,以便实现类似栈的行为

    var colors = ["red", "blue"];
    colors.push("brown"); // 添加另一项
    colors[3] = "black"; // 添加一项
    alert(colors.length); // 4
    var item = colors.pop(); // 取得最后一项
    alert(item); //"black"
    

    队列方法:

    队列数据结构的访问规则是 FIFO (First-In-First-Out,先进先出) 。

    队列在列表的末端添加项, 从列表的前端移除项。结合使用 shift() 和 push() 方法,可以像使用队列一样使用数组。

    var colors = new Array(); //创建一个数组
    var count = colors.push("red", "green"); //推入两项
    alert(count); //2
    count = colors.push("black"); //推入另一项
    alert(count); //3
    var item = colors.shift(); // 取得第一项
    alert(item); //"red"
    alert(colors.length); //2
    

    如图所示:

    栈方法:                           队列方法:

    2、数组的去重

    个是在实际应用中和面试中经常遇到的问题。所以提供以下的几种解决办法:

    在介绍去重的方法之前,先了解数组的indexOf方法,因为下面会用到。

    indexOf()方法返回在该数组中第一个找到的元素位置,如果它不存在则返回-1。 

    var a = ['red', 'blue', 'green', 'blue'];
    
    console.log(a.indexOf("blue"));  // 1
    console.log(a.indexOf("black"));  // -1
    

      

    方法1:遍历数组法

    function unique(array){
    	var n = []; 
    	
    	for(var i = 0; i < array.length; i++){
    
    		 //如果当前数组的第i已经保存进了临时数组,那么跳过,
    
    		 //否则把当前项push到临时数组里面
    		 if (n.indexOf(array[i]) == -1){
    		 	n.push(array[i]);
    		 }
    	}
    
    	return n;
    }
    
    var testArry=[1,2,5,5,6];
    console.log(unique(testArry));  //[1, 2, 5, 6]
    

    方法1缺点:IE8以及IE8以下不支持 indexOf

    方法2:对象键值对法

    function unique(array){
    	var n = {};
    	var r = [];
    	var len = array.length;
    	var val;
    	var type;
    
    	for (var i = 0; i < array.length; i++) {
    	     val = array[i];
    	     type = typeof val;
    
    	     if (!n[val]) {
    
    	         n[val] = [type];
    	        
    	         r.push(val);
    
    	     } else if (n[val].indexOf(type) < 0) {
    
    	         n[val].push(type);
    	         r.push(val);
    	     }
    
    	 }
    
    	 return r;
    	 
    }
    
    var testArry=["hello",2,5,5,6,"hello"];
    console.log(unique(testArry));  //["hello", 2, 5, 6]
    

      

    比较不好理解,稍作解释:

      新建一js对象以及新数组,遍历传入数组时,判断值是否为js对象的键,不是的话给对象新增该键并放入新数组。

      可以看看n返回的是什么: Object {2: ["number"], 5:["number"], 6: ["number"], hello: ["string"]}  ,让数组中的值作为对象的键,并让它的值只有一个数组

    方法2优缺点:优点:速度最快。   缺点:占空间最多(空间换时间)

    方法3:数组下标判断法

    function unique(array){
    	var n = [array[0]]; //结果数组
    	//从第二项开始遍历
    	for(var i = 1; i < array.length; i++) {
    	 //如果当前数组的第i项在当前数组中第一次出现的位置不是i,
    	 //那么表示第i项是重复的,忽略掉。否则存入结果数组
    		 if (array.indexOf(array[i]) == i){
    		 	n.push(array[i]);
    		 }
    	}
    	return n;
    }
    var testArry=["hello",2,5,5,6,"hello"];
    console.log(unique(testArry));  //["hello", 2, 5, 6]
    

    类似方法1,将不重复的放到数组中,然后返回

    方法4:给传入数组排序,排序后相同值相邻,然后遍历时新数组只加入不与前一值重复的值。

    function unique(array){
    	// 按从小到到排序
    	array.sort();
    	var re=[array[0]];
    	for(var i = 1; i < array.length; i++){
    
    		 if( array[i] !== re[re.length-1]) {
    
    		   	re.push(array[i]);
    		 }
    	}
    	return re;
    }
    var testArry=["hello",2,5,5,6,"hello"];
    console.log(unique(testArry));  //[2, 5, 6, "hello"]
    

    5.优化遍历数组法

    实现思路:获取没重复的最右一值放入新数组。(检测到有重复值时终止当前循环同时进入顶层循环的下一轮判断)

    function unique(array){
    	var r = [];
    	for(var i = 0, l = array.length; i < l; i++) {
    
    		for(var j = i + 1; j < l; j++){
    
    			    if (array[i] === array[j]) {
    
    			   		j = ++i
    			   	}
    		}
    
    		r.push(array[i]);
    	}
    
    	return r;
    }
    var testArry=["hello",2,5,5,6,"hello"];
    console.log(unique(testArry));  //[2, 5, 6, "hello"]
    

     

    方法6、简单法,类似于方法1.

    function unique(array){
      var arr=[];
      var obj={};
      for(var i=0;i<array.length;i++){
        if(!obj[array[i]]){
          obj[array[i]]=array[i];
          arr.push(array[i]);
        }
      }
      return arr;
    
    }
    
      var testArry=["hello",2,5,5,6,"hello"];
     console.log(unique(testArry));  //["hello", 2, 5, 6]
    

     因为简单,也是我最喜欢用的,哈哈

      

    3、迭代方法

    ECMAScript5为数组定义了5个迭代方法。

    1、forEach    遍历数组一次对数组中的各个项

    可以使用三个参数:数组对象、元素索引以及数组本身

     

    var testArry=["hello",2,5,6];
    
    testArry.forEach(function (item, index, array) {
    
      console.log(item); //hello 2 5 6
      console.log(index); // 0 1 2 3
      console.log(array); // ["hello",2,5,6]  输出4遍
    
    });
    

     

    2、every() 返回一个布尔值(truefalse),判断每个数组项是否符合指定函数的条件,符合为true,反之为false

    var testArry=[10,8,5,6];
    
    var isBiggerThan7 = testArry.every(function(ele,index,arr){
    
         return (ele >= 7);
    });
    
    if (isBiggerThan7) {
        console.log('都大于等于7');
    } else {
        console.log('不全都大于等于7');
    }
    
    //不全都大于等于7
    

      

    3、some()   返回一个布尔值(true或false),判断每个数组项是否符合指定函数的条件,只要有任何一项返回为true,就会返回true

    var testArry=[10,8,5,6];
    
    var isBiggerThan7 = testArry.some(function(ele,index,arr){
      
         return (ele >= 7);
    });
    
    if (isBiggerThan7) {
        console.log('有大于等于7的元素');
    } else {
        console.log('没有大于等于7的元素');
    }
    
    //有大于等于7的元素
    

      

    4  filter(): 每个数组项调用指定的函数,条件为true的将返到一个新数组中.相当于是筛选数组里面的内容

    var testArry=[10,8,5,6];
    
    var BiggerThan7 = testArry.filter(function(ele,index,arr){
        if(ele >= 7){
    
            return true;
        }
    });
    
    console.log(BiggerThan7);   //[10, 8]

    5、map() 每个数组项调用指定的函数,返回每次函数调用的结果组成一个新数组  

    用法基本和forEach一样,但是有个区别,forEach没有返回值,map有返回值

    var testArry=[10,8,5,6];
    
    var newArry1 = testArry.map(function(ele,index,arr){
        if(ele >= 7){
    
            return true;
        }
    });
    
    console.log(BiggerThan7);   //[true, true, undefined, undefined]
    
    // -----------------------------------------------------------------------------
    
    var newArry2 = testArry.forEach(function(ele,index,arr){
        if(ele >= 7){
    
            return true;
        }
    });
    
    console.log(newArry2);   //undefined
    

      

    4、归并方法

    ECMAScript5 有2个归并数组的方法:reduce()和reduceRight()。

    1、reduce():从第一项开始逐个遍历到最后。它接收两个参数 array.reduce(callback, initialValue),

        callback 函数接受4个参数:之前值、当前值、索引值以及数组本身。

       initialValue可选,表示初始值。若指定,则当作最初使用的previous值;如果缺省,则使用数组的第一个元素作为previous初始值,同时current往后排一位

    initialValue的用法还不是很清楚。欢迎补充

     var testArry=[10,8,5,6];
    
    var result = testArry.reduce(function(previous, current, index, array){
                return previous+current;
    });
    
    console.log(result);   //29
    
    
    

    2、reduceRight(): 从数组的最后一项开始,遍历到数组的第一项。

    用法同reduce基本一样,只是开始的位置从右边第一位开始,区别仅此而已

    var testArry=[10,8,5,6];
    var initialValue=10;
    
    var result = testArry.reduceRight(function(previous, current, index, array){
    
    	          return previous+current;
    });
    
    console.log(result);   //29
    

      

    三、数组的算法

    获取最大值和最小值

    方法一:遍历

      获取最大值

    function getMax(arr){
        if(!(arr instanceof Array)){
            return;
        }
        var max=arr[0];
        for(var i=0,len=arr.length;i<len;i++){
            if(arr[i]>max){
                max=arr[i];
            }
        }
        return max;
    }
    var maxNum=getMax([1,3,5,7,10]);
    alert(maxNum); //10

      获取最小值

    function getMin(arr){
        if(!(arr instanceof Array)){
            return;
        }
        var min=arr[0];
        for(var i=0,len=arr.length;i<len;i++){
            if(arr[i]<min){
                min=arr[i];
            }
        }
        return min;
    }
    var minNum=getMin([3,3,1,7,10]);
    alert(minNum); //1

    方法二: 原型方法:(利用apply方法来调用原生的Math.max与Math.min方法来求得结果)

      获取最大值:

    Array.prototype.getMax=function(){
    	return Math.max.apply({},this);
    }
    var maxNum=[1,3,5,7,10].getMax();
    alert(maxNum);  //10
    

      获取最小值:

    Array.prototype.getMin=function(){
    
        return Math.min.apply({},this);
    }
    var minNum=[1,3,5,7,10].getMin();
    alert(minNum);  //1

    数组的排序(从小到大或者从大到小)

    sort:直接使用不能达到效果,需要传个函数

    var arr=[3,9,1,7,10];
    alert(arr.sort()); // 1,10,3,7,9

    需要这样

    function sortArray(a,b){
        return a-b;
    }
    var arr=[3,9,1,7,10];
    var minToMax=arr.sort(sortArray);
    alert(minToMax); // 1,3,7,9,10  从小到大
    var maxToMin=arr.sort(sortArray).reverse();
    alert(maxToMin); // 10,9,7,3,1  从大到小

    四、es6新增加的数组方法

    1、Array.from()

    Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括es6新增的数据结构Set和Map)。

    需要注意以下三点:


     1、任何有length属性的对象,都可以通过Array.from方法转为数组。


     2、传参为类数组对象 就是类似数组结构的对象,比如key值为数字啊什么的


     3、Array.from是通过key作为下标并且参照length属性大小来填充元素的。当没有合适的元素插入时就会插入undefined补位。

    直接上代码:

    var a = Array.from('hello');
    console.log(a);// ['h', 'e', 'l', 'l', 'o']
    
    
    // 没有传length,结果返回了一个空数组,验证了第一个注意点
    var obj={"name":"咸鱼","age":"24","sex":"男"}
    console.log(Array.from(obj));  //[]
    
    // 有传length,但不是类数组,返回三个undefined, 验证了第二个,第三个注意点            
    var obj2={"name":"咸鱼","age":"24","sex":"男",length: 3};
    console.log(Array.from(obj2));  //[undefined, undefined, undefined]
    
    // 有传length,并且对象是类数组
    var obj3={"0":"咸鱼","1":"24","2":"男",length: 3}
    console.log(Array.from(obj3));   //["咸鱼", "24", "男"]
    
    
    // key值不从0起,验证了注意点3
    var obj4 = { "1":"咸鱼","2":"24","3":"男",length: 3};
    console.log(Array.from(obj4));  //[undefined, "咸鱼", "24"]

    2、Array.of();

    Array.of方法用于将一组值,转换为数组

    var a=Array.of(3,9,10);  
    var b=Array.of(3);  
    
    console.log(a);  //[3, 9, 10]
    console.log(b);  //[3]
    console.log(b.length);  //1
    

    跟普通的数组有什么区别呢,普通的数组只有当参数个数不少于2个时,才会返回由参数组成的新数组。参数个数只有一个时,实际上是指定数组的长度。

    下面是普通的数组,可以看看参数只有一个的区别:

    var a=Array(3,9,10);  
    var b=Array(3);  
    
    console.log(a);  //[3, 9, 10]
    console.log(b);  //[,,,]
    console.log(b.length);  //3
    

      

     

    3、find()和findIndex()

     数组实例的find方法,用于找出第一个符合条件的数组成员, 它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined。

     数组实例的findIndex方法的用法与find方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。类似于indexOf();
     
     
    var array=[3, 9, 10,15,6,20];
    
    // find
    var fn=array.find(function(value,index,arr){
    	
    	return value>10;
    });
    console.log(fn);  //15  当找到这个值的时候,就会停止继续查找
    
    
    var fn2=array.find(function(value,index,arr){
    	
    	return value>30;
    });
    console.log(fn2);  //undefined
    
    // -----------------------------------------------------------------
    
    // findIndex
    var fn3=array.findIndex(function(value,index,arr){
    
    	return value>10;
    });
    console.log(fn3);  //3  
    
    var fn4=array.findIndex(function(value,index,arr){
    
    	return value>30;
    });
    console.log(fn4);  //-1 
    

      

    4、fill()

    fill方法使用给定值,填充一个数组,fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置
     
    var array=['a','b','c'];
    array.fill(7);
    console.log(array);  //[7, 7, 7]
    
    
    var array2=['a','b','c','d','e'];
    array2.fill(7,1,3); //在下标为 1和2的位置插入7
    console.log(array2);  //["a", 7, 7, "d", "e"]
    

      

    有误之处,欢迎指出

  • 相关阅读:
    LeetCode对撞指针汇总
    167. Two Sum II
    215. Kth Largest Element in an Array
    2018Action Recognition from Skeleton Data via Analogical Generalization over Qualitative Representations
    题解 Educational Codeforces Round 84 (Rated for Div. 2) (CF1327)
    题解 JZPKIL
    题解 八省联考2018 / 九省联考2018
    题解 六省联考2017
    题解 Codeforces Round #621 (Div. 1 + Div. 2) (CF1307)
    题解Codeforces Round #620 (Div. 2)
  • 原文地址:https://www.cnblogs.com/xianyulaodi/p/5444874.html
Copyright © 2011-2022 走看看