JS基础之数组

数组的基础结构:

数组也是对象数据类型的 typeof []->'object'
数组也有属性名,只不过属性名为数字,我们把数字属性名称之为它的索引:数组是以数字作为索引,索引从零开始,有一个length属性,代表数组的长度
类数组:类似于数组,但不是数组
1.通过getElementByTagName获取的元素集合是类数组
2.函数中的实参集合arguments也是类数组 ->document.getElementByTagName('*')
循环数组中的每一项

 var ary=[12,23,34];
 //for循环操作
 for(var i=0;i<ary.length;i++){
     // ary[i]获取每一项
 }
 //for in 循环
  for(var key in ary){
     console.log(ary[key])
  }  
  //for 循环和for in 循环的区别
   //for循环只能遍历数组私有属性
   //for in可以遍历到自定义的公共属性  

数组中的常用方法

数组中有很多常用的方法(使用数组方法需要考虑以下几点:)
1.方法的意义和作用
2.方法的形参
3.方法的返回值
4.通过此方法,原来的数组是否发生改变

实现数组的增加、修改、删除、查询

  • 增加:push 参数可以为1到多个,可以传递多个,用逗号隔开,向数组的末尾增加新内容 返回数组的长度 原数组改变;数组里边的每一项值可以是任意类型值
    unshift:向数组的开头追加新元素,参数可以为1到多个,传递多个用逗号隔开,返回数组的长度 原数组改变;
    arr[arr.length]=xxx;可以把数组当做普通对象,使用对象键值对操作,向数组的末尾增加新的内容
  • 删除:pop 删除数组最后一项,不支持参数,返回被删除的那一项内容,原有数组改变
    shift:删除数组第一项,不支持参数,返回被删除的那一项内容,原数组改变,后面每一项的索引都要向前进一位,导致后面的索引发生改变
    delete arr[索引] 把数组当成普通对象操作 删除指定索引对象,原有数组其他项索引不会改变 返回true,当前数组的length不会改变  
    arr.length--:删除数组最后一项
    splice:数组中内置的方法,可以实现数组的增加、修改、删除 返回被删除的内容(以一个新数组保存被删除的内容),原有数组改变
    splice(n,m):从索引n开始删除m个(m不写是删除到数组末尾);不带参数一项也不删除,返回空数组,splice(0)清空数组
    splice实现修改 splice(n,m,x)在原有删除的基础上用x代替删除的内容
    splice实现增加(n,0,x):在修改的基础上,一项都不删除,把x插入到索引n的前面,返回空数组
    arr.splice(0,0,x) 向数组开头追加新的内容
    arr.splice(arr.length,0,x) 向数组末尾增加新内容
    arr.splice(0,1) 删除第一项 arr.splice(ary.length-1)删除最后一项 
    查询 :slice 参数(n,m)从索引n开始找到索引m处(不包含m),返回找到的部分以新数组返回;原数组不变,如果只写n 从索引n开始找到末尾 如果写个0或者不写 数组克隆,克隆一份和原来数组一模一样的新数组
    支持负数索引,如果索引为负数,浏览器解析的时候是按照 总长度+负数索引来处理的
  • 拼接:concat 将多个数组拼接在一起,参数是要拼接的内容,可以是数组,也可以是一些数据值;返回拼接后的新数组,原数组不变;如果不带参数,什么都没有拼接,相当于把原有数组克隆一遍
  • 转为字符串: toString 实现把数组转换为字符串(转换后的字符串以逗号分隔每一项),不需要参数,返回转换的字符串,原数组不变
    join 把数组按照指定的分隔符转为字符串,和字符串中的split相对应 参数:指定的链接符,返回转换后的字符串,原数组不变,如果不带参数返回只有长度为一的数组;可用于数组求和
// 数组求和
//     1.循环求和
    var total=null;
    for(var i=0;i<arr.length;i++){
        total+=arr[i]
    }
 //第二种用join
  eval(arr.join('+'))//evel:把字符串转换为JS表达式执行  
  • 排列:reverse 把数组中的每一项倒过来排列,不需要参数,返回排序后的数组,原数组改变
  • 排序: sort 实现数组的排序 无参数或者一个回调函数,返回排序后的数组,原数组改变,不传参数的情况下:可以给10以内的数字进行升序排列,但是超过10的就无法处理了(多位数只识别第一位),解决:sort(function(a,b){return a-b;}) a-b 升序 b-a 降序
  • 验证数组中是否包含某一项:indexof/lastIndexof 获取当前项在数组中第一次/最后一次出现的位置的索引,如果当前数组中没有返回-1;用于验证是否包含,数组中的这两个方法不支持IE6-8但是字符串中的这两个方法支持所有浏览器
Array.prototype.myIndexOf=function myIndexOf(value) {
     var result=-1;
     for(var i=0;i<this.length;i++){
         if(value===this[i]){
             result=i;
             break;
         }
     }
     return result;
}

遍历数组的方法:以下的方法在IE(6-8)都不兼容

  • forEach 遍历数组中的每一项
  • map:遍历数组中的每一项,在forEach的基础上,可以修改每一项的值
  arr.forEach(function(value,index){
        /*数组中有多少项,当前回调函数就执行多少次;每一次传递进来
        的value就是当前遍历数组这一项的值,index就是遍历这一项的索引
         */
    })
 arr.map(function(value,index){
        /*数组中有多少项,当前回调函数就执行多少次;每一次传递进来
        的value就是当前遍历数组这一项的值,index就是遍历这一项的索引
         */
        return xxx;//return 后面返回的结果就是把当前遍历的对象修改为xxx
    })

数组去重

  • 方案一:遍历数组中的每一项,拿每一项和它后面的项一次比较,如果相同了,则把相同的这一项在原来的数组中删除即可,缺点:性能不好 循环次数太多
    数组塌陷:我们使用splice删除数组中的某一项后,删除的这一项,后面的每一项索引都要向前进一位(在原有索引上减一),此时如果我们j++,循环操作的值增加了,我们通过最新j获取的元素不是紧挨删除这一项的元素,而是跳过这一项元素
var arr=[1,2,3,1,2,3,345,12,4,43,213,11,3,5,3,3,6];
//length-1:最后一项后面没有内容了,我们不需要在比较
for(var i=0;i<arr.length-1;i++){
   var cur=arr[i]//当前遍历的这一项(索引为i)
     //把拿出的这一项和后面的每一项进行比较
     //i+1:把当前项和它后面项比较,当前项索引是i;后一项索引是i+1
   for(var j=i+1;j<arr.length;j++){
       //arr[j]:作比较的那一项
      // cur===arr[j]?arr.splice(j,1):j++;另一种解决塌陷方法
       if(cur===arr[j]){
      /*本次作比较的这一项和当前项相同,我们需要再原有
       数组中把作比较的这一项删除调(作比较的索引是j)
       数组塌陷:我们使用splice删除数组中的某一项后,删除的这一项
       后面的每一项索引都要向前进一位(在原有索引上减一),此时
       如果我们j++,循环操作的值增加了,我们通过最新j获取的元素不是
       紧挨删除这一项的元素,而是跳过这一项元素
           */
       arr.splice(j,1);
       j--;//先让j--;然后在++;相当于没加没减,此时索引还是原有索引
           //在获取的时候就是删除这一项后面的紧挨着的这一项
       }
   }
}
console.log(arr);
  • 方案二:利用indexOf来验证数组中是否包含某一项,包含包当前项删除掉(不兼容ie(6-8))
 var arr=[1,2,3,1,2,3,345,12,4,43,213,11,3,5,3,3,6];
 for(var i=0;i<arr.length;i++){
     var cur=arr[i];
     // 把当前项后面的那些值以一个新数组返回,
     // 我们需要比较的就是后面的这些项对应的新数组
     var curNextArr=arr.slice(i+1);
     if(curNextArr.indexOf(cur)>-1){
        //后面的就包含当前项(当前这一项是重复的),删除即可
         arr.splice(i,1);
         i--;
     }
 }
 console.log(arr);
  • 方案三:
    原理:对象去重的方式,遍历数组中的每一项,把每一项的作为新对象的属性名和属性值存储起来,在每一次向对象中存储之前,首先看一下原有对象中是否包含了这个属(typeofobj[xxx]==='undefined' 说明当前对象中没有xxx这个属性)如果已经存在这个属性,说明数组中的当前项是重复的(1在原有的数组中删除这一项2不在向对象中存储这个结果),如果不存在(把当前项)作为对象的属性名和属性值存储进去即可)
  var arr=[1,2,3,1,2,3,345,12,4,43,213,11,3,5,3,3,6];
    var obj={};
    for(var i=0;i<arr.length;i++){
        var cur=arr[i];
        if(typeof  obj[cur]!=='undefined'){
            //对象中已经存在改属性:证明当前项是数组中的重复项
            //使用splice会导致后边的索引向前提一位,如果后面有很多
            //消费性能很大  思路:我们把最后一项那来替换当前项
            //然后在把最后一项删除
            //arr.splice(i,1);
            arr[i]=arr[arr.length-1];
            arr.length--;
            i--;
            continue;
        }
        obj[cur]=cur;
    }
    console.log(arr)
Array.prototype.myUnique=function myUnique() {
    var obj={};
    for(var i=0;i<this.length;i++){
        var item=this[i];
        if(typeof obj[item]!=='undefined'){
            this[i]=this[this.length-1];
            this.length--;
            i--
            continue;  
        }
        obj[item]=item;
    }
}

数组排序(算法)
-冒泡排序:让数组中的当前项和后一项进行比较,如果当前项大于后一项,我们让两者交换位置(小->大) 一轮不能完成比较,每一轮都能把当前最大的放到末尾 具体比较的轮数 arr.length-1

  /*bubble 冒泡排序
     @parameter
     arr:[array] 需要实现排序的数组
     @return
      [array]排序后的数组(升序)
      by team on 2019/3/6
     */
function bubble(arr) {
    //外层循环控制比较轮数
    for(var i=0;i<arr.length-1;i++){
        //里层循环控制每一轮比较的次数
        for(var j=0;j<arr.length-1-i;j++){
           //cur=arr[j]//当前拿出来的这一项
           //arr[j+1]//当前项的后一项
            if(arr[j]>arr[j+1]){
                //当前项比后一项大,我们交换位置
                var temp=arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=temp;
            }
        }
    }
    return arr;
}

递归:函数自己调用自己

   //1-100之间,把所有能被3并且被5整除的获取到,然后累加求和
     var total=null;
    function fn(num) {
        if(num>100){
            return 0;
        }
        if(num%15===0){
            return num+fn(num+1)
        }
        fn(num+1)
  }
  fn(1)
  • 快速排序:先找中间项,然后把余项中的每一个值和中间相进行比较,小的放左边,大的放右边,然后左边右边重复执行
 function quick(arr) {
     //如果传递进来的数组只有一项或者是空的,我们则不再继续拆分了
     if(arr.length<=1){
         return arr;
     }
     //获取中间项索引:把中间值获取到,原有数组中删除中间项
     var centerIndex=Math.floor(arr.length/2);
     var centerValue=arr.splice(centerIndex,1)[0];//返回数组
     //用剩余数组中的每一项和中间项比较,小的在左边,大的在右边
     var leftArr=[],rightArr=[];
     for(var i=0;i<arr.length;i++){
        var cur=arr[i];
        cur<centerValue?leftArr.push(cur):rightArr.push(cur)
     }
    return quick(leftArr).concat(centerValue, quick(rightArr))
 }

类数组:
元素集合是类数组
var Oli=document.getElementsByTagName('div');
节点集合也是类数组
var oLi=document.getElementsByName('div');
在IE6-8中,元素集合和节点集合的类数组 不支持借用数组slice实现类数组变为数组
arguments支持
var Oli=document.getElementsByTagName('div');
var ary=Array.prototype.slice.call(Oli);
console.log(ary)
解决兼容:
for(var i=0;i<oli.length;i++){
arr[ary.length]=oli[i]
}

  //处理IE不兼容类数组转为数组 
   listToArray:function (likeAry) {
           var arr=[];
           try{
            arr=Array.prototype.slice.call(likeAry)
           }catch(e){
                for(var i=0;i<likeAry.length;i++){
                  arr[arr.length]=likeAry[i]
                }
           }
           return arr;
       }
 function avgFn() {
        /*arguments是类数组,不能使用数组 方法 sort;将数组转为数组
        数组slice()是克隆数组,可以借鉴封装一个克隆的方法
        Array.prototype.mySlice=function () {
        var arr=[];
        for(var i=0;i<this.length;i++){
            arr[arr.length]=this[i]
        }
        return arr;
       }
       2.循环遍历
       var arr=[];
        for(var i=0;i<arguments.length;i++){
         arr[arr.length]=arguments[i]
        }
      3.用数组slice,在slice执行的时候,让方法中的this变为我们
        要处理的arguments,实现将类数组变为数组
          var arr=Array.prototype.slice.call(arguments)
          arr=[].slice.call(arguments)
      */
     var arr=Array.prototype.slice.call(arguments)
     arr=[].slice.call(arguments)
     arr.sort(function (a,b) { return a-b });
     arr.shift();
     arr.pop();
     return eval(arr.join('+'))/arr.length
    }
    var res=avgFn(9.8,8.6,7.3,10,9.9,9.0,9.6,3.0).toFixed(2);
    console.log(res);
    //借用数组的方法,必须为类数组
    function avFn() {
        Array.prototype.sort.call(arguments,function (a,b) {
            return a-b
        });
        [].shift.call(arguments);
        [].pop.call(arguments)
        return (eval([].join.call(arguments,'+'))/arguments/length).toFixed(2)
    }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,045评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,114评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,120评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,902评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,828评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,132评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,590评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,258评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,408评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,335评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,385评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,068评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,660评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,747评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,967评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,406评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,970评论 2 341

推荐阅读更多精彩内容

  • 一、数组 1. 定义 数组(array)是按次序排列的一组值。每个值的位置都有编号(从 0 开始),整个数组用方括...
    养乐多__阅读 648评论 0 1
  • JavaScript 数组的力量隐藏在数组方法中。 把数组转换为字符串 toString() JavaScrip...
    贤总_阅读 150评论 0 0
  • 今天来讲一下我们js中常用的数组 数组是引用数据类型中的对象数据类型(特殊对象) *创建一个数组,也是要开辟一个堆...
    小晨的世界阅读 1,567评论 0 1
  • 什么是数组? 数组是一种特殊的变量,它能够一次存放一个以上的值。 如果您有一个项目清单(例如,汽车品牌列表),在单...
    贤总_阅读 310评论 0 0
  • 数组方法 下面开始介绍数组的方法,数组的方法有数组原型方法,也有从object对象继承来的方法,这里我们只介绍数组...
    祈求者阅读 366评论 0 2