数组与数组API(String,join,concat,slice,splice,reverse)-06

2016-08-26-day06-am


1.数组

  • 什么是:内存中,连续存储多个数据的存储空间,再起一个名字
    一组变量的集合
  • 为什么:现实中存储多个相关数据,都是集中存储,共用同一个名字。
    程序=数据结构+算法
    好的数据结构可以极大的提高程序的执行效率
  • 何时:今后只要连续存储多个相关的数据都要用数组
  • 如何使用: 创建数组的3种方法如下:
1.创建空数组: 2种:
   数组直接量: var arr=[];
   用new: var arr=new Array();
2.创建数组同时,初始化数组的数据:
数组直接量: var arr=[值1,值2,...]
用new:  var arr=new Array(值1,值2,...);
3. 创建n个空元素的空数组:
  1.只能用new: var arr=new Array(n);
  • 访问数组中的元素:
    下标: 数组中唯一标识一个元素存储位置的序号
    默认从0开始,连续递增,不重复
    arr[i]: 访问下标为i位置的元素
    数组中,每个元素的用法和普通变量完全一样。
  • 数组的length属性:
    标识了数组中理论上的元素个数
    任何情况下: length永远是最大下标+1
    固定套路:
最后一个元素: arr[arr.length-1]
倒数第n个元素: arr[arr.length-n]
追加新元素:arr[arr.length]=新值;
缩容: arr.length--;

以下是一个简单的数组例子

<!doctype html>
<html>
    <head>
        <title></title>
        <meta charset="utf-8">
    </head>
    <body>
        <script>
      var arr=["一","二","三","四","五"];
             // 0    1    2    3    4
      console.dir(arr);
      console.log(arr[2]);//获取下标2位置的元素值
      //取出下标2位置的值,拼上"星期",再放回2位置
      arr[2]="星期"+arr[2];
      //获取元素时越界,不报错,返回undefined
      console.log(arr[10]);
      //设置元素时越界,自动添加新元素
      arr[6]="星期日";
      //固定套路: 
      console.log(
        arr[arr.length-1],//倒数第一个元素
        arr[arr.length-3]//倒数第三个元素
      );
      arr[arr.length]="星期八";//末尾追加新元素
           </script>
    </body>
</html>
  • 特殊情况: js中的数组:3个不限制
    1.不限制元素的数据类型
    2.不限制下标越界
    获取元素值:
    下标越界: 不报错,返回undefined
    3.不限制元素的个数
    设置元素值:
    下标越界:
    自动在指定位置添加新元素
    自动修改length为最大下标+1
    稀疏数组: 下标不连续的数组
  • 遍历数组: 依次访问数组中每个元素
    for(var i=0;i<arr.length;i++){
       arr[i]//当前元素
    }

以下几个与数组有关的小练习

<!doctype html>
<html>
  <head>
    <title></title>
    <meta charset="utf-8">
  </head>
  <body>
    <script>
    /*
      var emps=[];//创建空数组emps
      //声明ename为空字符串
      var ename="";
      //反复执行: //请用户输入员工姓名,保存在ename中,如果ename不是exit
      while((ename=prompt("输入姓名"))!="exit"){
        //将ename追加到数组emps末尾
        emps[emps.length]=ename;
      }
      //输出:
      console.dir(emps);
    */
    /*
      //找出数组中一个最大值:
      var arr=[1,2,3,4,3,2,1];
          //                 max=4
      function getMax(arr){
        //遍历arr中每个元素,同时声明变量max,赋值为数组第1个元素
          //如果当前元素>max,就将max赋值为当前元素
        for(var i=0,max=arr[0];
            i<arr.length;
            arr[i]>max&&(max=arr[i]),i++);
        return max;//返回max
      }
      console.log(getMax(arr));//4
    */
      var arr=[1,2,3,2,1];
            // 0 1 2 3 4
      //定义indexOf函数
        //可以从指定位置开始,查找下一个指定值得下标位置
        //如果找不到,返回-1
      function indexOf(arr,val,fromi){
        //如果fromi是undefined就赋值为0
        fromi===undefined&&(fromi=0);
        //从fromi开始,遍历arr中剩余元素
        for(;fromi<arr.length;fromi++){
          //如果当前元素等于val
          if(arr[fromi]==val){
            return fromi;//返回fromi
          }
        }//(遍历结束)
        return -1; //返回-1
      }
      //在arr中从0位置开始找下一个元素值为2的位置
      console.log(indexOf(arr,2));//1
      //在arr中从2位置开始找下一个元素值为2的位置
      console.log(indexOf(arr,2,2));//3
      //在arr中从4位置开始找下一个元素值为2的位置
      console.log(indexOf(arr,2,4));//-1
      //在arr中从0位置开始找下一个元素值为4的位置
      console.log(indexOf(arr,4));//-1
    </script>
  </body>
</html>
  • 数组是引用类型的对象:
    引用类型的例子
<!doctype html>
<html>
  <head>
    <title></title>
    <meta charset="utf-8">
  </head>
  <body>
    <script>
      //按值传递:两个变量间赋值时,或将变量作为参数传入函数时,其实仅将原变量中的值复制一个副本给对方
      //原始类型的值: 修改新变量,不影响原变量
      var a=3;
      var b=a;//a将自己的值复制了一个副本给b
      a++;
      console.log(b);//3
      console.log(a);//4

      var card=10;
      function buy(card){
        card-=3;
        console.log("余额"+card);
      }
      buy(card);//7
      console.log(card);//10

      //引用类型的对象: 用原变量修改对象,新变量同样受影响。因为两个变量引用的是同一个对象
      var dd=["包","包","包","包","包"];
    /*
      var xx=dd;
      dd.length--;
      console.log(String(xx));//4个
      console.log(String(dd));//4个
      xx.length--;
      console.log(String(xx));//3个
      console.log(String(dd));//3个
    */
      function eat(arr){
        arr.length--;
        console.log(arr.length);
      }
      eat(dd);//4
      console.log(dd.length);//4
    </script>
  </body>
</html>

pm


1.垃圾回收: 定期回收不再被任何变量引用的对象。释放内存。
  1. 垃圾回收器:
    伴随主程序,并行运行的一个小程序
    定期回收内存中的不再被任何变量引用的对象。
  2. 引用计数器:
    每个对象上,标记正在引用对象的变量个数的一个属性
    每多一个变量引用对象,计数器就+1
    如果一个变量通过赋值为null释放对对象的引用,则计数器-1
    直到计数器为0,表示不再有任何变量引用该对象,则该对象被回收/释放
    建议: 如果使用完较大的对象,都要主动赋值为null。
2.关联数组:
  • 什么是:可自定义下标名称的数组
  • 为什么:普通的索引数组的下标都是无意义的数字。不便于快速查找元素。也容易出现歧义.
    [林心如, 81, 53, 86]
    name math chs eng
  • 何时:希望每个元素有专门的名称时
    通常用于快速定位元素
  • 如何使用: 创建: 2步:
     1.创建空数组: var lxr=[];
     2.向空数组中添加新元素: 
        使用自定义的字符串元素名作为下标
       lxr["name"]="林心如";
       lxr["math"]=81;
       lxr["chs"]=53;
       lxr["eng"]=86;
  • 访问元素: lxr["name"]
  • 强调: 关联数组的length失效
  • 遍历: 不能用for循环
    用for in循环: 其中in,表示依次取出数组中每个下标
      for(var key in hash){
         key//每个元素的下标名称
             hash[key]//当前元素值
      }
  • 关联/hash数组原理:
    hash算法: 接收一个字符串,并计算出一个尽量不重复的序号
    相同的字符串,计算出的号总是一样的
    不同的字符串,计算出的号大多数不重复
    存入数据:
    hash算法接收一个字符串的下标名,计算出一个不重复的序号。将数据存储在序号对应的数组位置上
    获取数据:
    将下标名称交给hash算法,算出和存入时完全相同的序号,直接去序号位置查找元素
    优点: 查找极快!
    和数组中元素个数,以及元素在数组中的位置无关。
    以下是hash的简单例子:
<!doctype html>
<html>
  <head>
    <title></title>
    <meta charset="utf-8">
  </head>
  <body>
    <script>
    /*
      var lxr=[];
      lxr["name"]="林心如";
      lxr["math"]=81;
      lxr["chs"]=53;
      lxr["eng"]=86;
      console.dir(lxr);
      console.log(lxr["math"]);
      //遍历:
      for(var key in lxr){
                  //name : 林心如
        console.log(key+":"+lxr[key]);
      }
    */
      var arr=["a","b","a","c","a","b"];
      function unique1(arr){
        //遍历arr中每个元素,同时声明空数组uarr
        for(var i=0,uarr=[];i<arr.length;i++){
          //遍历uarr中每个元素
          for(var j=0;j<uarr.length;j++){
           //如果uarr中当前元素等于arr中当前元素
            if(uarr[j]==arr[i]){
              break;//就退出循环
            }
          }//(遍历结束)
          //如果j等于uarr的length
            //将arr中当前元素加入uarr中
          j==uarr.length&&(uarr[j]=arr[i]);
        }//(遍历结束)
        return uarr;//返回uarr
      }      
      function unique2(arr){
        //遍历arr中每个元素,同时创建空数组hash
        for(var i=0,hash=[];i<arr.length;i++){
          //如果hash中以arr中当前元素值为key的元素等于undefined
          if(hash[arr[i]]===undefined){
            //就在hash中添加一个新元素,key为arr中当前元素,值为1
            hash[arr[i]]=1;
          }
        }//(遍历结束)hash:["a":1,"b":1,"c":1]
        i=0;//设置i=0
        var keys=[]//定义空数组keys
        for(keys[i++] in hash);
        return keys;
      }
      var uarr=unique1(arr);
      console.log(String(uarr));//a,b,c
    /*
      //随机生成十万个0~999之间的数,放入数组arr
      for(var i=0,arr=[];i<100000;i++){
        arr[arr.length]=
          parseInt(Math.random()*1000);
      }
      //设置测试开始时间
      console.time("unique1");
      unique1(arr);//调用被测函数
      //设置测试结束时间,并打印时间差
      console.timeEnd("unique1");//ns
      console.time("unique2");
      unique2(arr);
      console.timeEnd("unique2");//ns
    */
    </script>
  </body>
</html>
数组API:

对象: 集中存储多个数据的一块存储空间, 并提供了操作数据的API
函数: 不属于任何对象的函数
方法: 必须用对象才能调动的函数,叫方法

  • 1. 转字符串: 2种
    1. 将数组中每个元素都转为字符串,再用逗号分隔: var str=String(arr);
    2. 将数组中每个元素都转为字符串,再用自定义下标连接每个元素:
      var str=arr.join("自定义连接符")
      强调:如果省略参数,默认等效于String

固定套路:
1. 无缝拼接: arr.join("")
2. 将单词拼接为句子: arr.join(" ")
3. 判断空数组: arr.join("")==""
4. 根据数组中的元素,动态生成页面元素的内容


例子:

<!doctype html>
<html>
  <head>
    <title></title>
    <meta charset="utf-8">
  </head>
  <body>
    <select id="sel">
    </select>
    <script>
      //无缝拼接
      var chars=["H","e","l","l","o"];
      console.log(chars.join(""));
      //单词拼接为句子
      var words=["no","zuo","no","die"];
      console.log(words.join(" "));
      //判断空数组
      var arr=[,,,,,,,,,];
      console.log(arr.join(""));
      //动态生成页面元素的内容
      var provs=["北京市","天津市","山东省","河南省","山西省"];
      var html="<option>"+
        provs.join("</option><option>")
        +"</option>";
      //设置id为sel的元素开始标签到结束标签之间的html内容
      sel.innerHTML=html;
    </script>
  </body>
</html>
  • 2. 拼接和截取:
    拼接:
    var newArr= arr1.concat(值1,值2,arr2,....)
    将值1,值2,以及arr2中每个元素依次拼接到arr1结尾,返回新数组。
    何时使用: 将多个元素或其他数组,拼接到当前数组上时

强调:
1.concat无权修改原数组,只能返回新数组
所以,必须用变量接住拼接后的返回值
2.concat可打散数组类型的参数为单个元素**

截取:(复制)
var subArr=arr.slice(starti,endi+1);
复制arr中starti位置开始到endi结束的元素组成子数组返回。
何时: 选取数组中指定位置的子数组时

强调:
1. 无权修改原数组,只返回新子数组
2.含头不含尾
3.其实可使用负数参数,表示倒数第n个

简写:
1. 省略第二个参数,表示一直截取到结尾
2. 两个都省略,表示完整复制原数组中的元素到新数组。
不能只省略第一个参数——报错
例子:

<!doctype html>
<html>
  <head>
    <title></title>
    <meta charset="utf-8">
  </head>
  <body>
    <script>
      var arr1=[1,2,3];
      //拼接
      var newArr=arr1.concat(12,23,[123,234]);
      console.dir(arr1);//原数组不变
      console.dir(newArr);//只返回新数组
      //[1,2,3,12,23,123,234]
      // 0 1 2 3  4   5  6
      //          3   2  1-
      //选取3到4位置的两个元素
      var subArr=//newArr.slice(3,4+1);
                 //newArr.slice(3);//选到结尾
                 //完整复制: 新数组和原数组不是同一个数组对象,地址不同
                 //newArr.slice();
                 //第一个参数不能省
                 //newArr.slice(0,3);
                 //可使用负数下标,表示倒数
                 //newArr.slice(-3,-2+1);
                 //其实是:
                 newArr.slice(newArr.length-3,
                              newArr.length-2+1)
      //var subArr=newArr;
      //两个对象做==比较,不比内容,而比地址!
      //console.log(subArr==newArr);//false
      console.log(String(newArr));
      console.log(String(subArr));
    </script>
  </body>
</html>
  • 3.splice: 删除,插入,替换

    删除数组中指定位置的元素:
    arr.splice(starti,n):
    删除arr中starti位置开始的n个元素
    其实: var deletes=arr.splice(starti,n)
    deletes: 返回的被删除的元素组成的临时子数组。

    在数组指定位置插入新元素:
    arr.splice(starti,0,值1,值2,...)
    在starti位置插入新值
    原starti位置的值被向后顺移

    强调: splice,不支持打散数组参数
    插入: splice vs concat
    concat只能在开头或结尾拼接,不能中间插入。但可打散数组类型参数
    splice可在任意位置插入,但不可打散数组类型参数。

替换数组中指定位置的元素
arr.splice(starti,n,值1,值2,...)
先删除starti位置的n个旧元素
再在starti位置插入新值

强调: 删除的个数和插入的个数不必一致
splice可自动调节数组的长度和位置

<!doctype html>
<html>
  <head>
    <title></title>
    <meta charset="utf-8">
  </head>
  <body>
    <script>
      var arr=[1,2,3,4,5];
            // 0 1 2 3 4
    /*
      //删除开头的2个元素,再拼接到arr结尾
      arr=arr.concat(arr.splice(0,2));  
      console.log(String(arr));//[3,4,5,1,2]
      //删除结尾的2个元素,再拼接到arr开头
      arr=arr.splice(arr.length-2,2).concat(arr)
      console.log(String(arr));
    */
      //arr.splice(2,0,12,23,[123,234]);
      //console.dir(arr);
      arr.splice(1,2,12,23,123);
      console.log(String(arr));
      //1,12,23,123,4,5
    </script>
  </body>
</html>
image.png

翻转: arr.reverse();

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352

推荐阅读更多精彩内容

  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 31,928评论 2 89
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,651评论 18 139
  • 概要 64学时 3.5学分 章节安排 电子商务网站概况 HTML5+CSS3 JavaScript Node 电子...
    阿啊阿吖丁阅读 9,180评论 0 3
  • Mac默认自带python开发环境 安装python开发环境Django. 指令为:pip install Dja...
    sk_lxf阅读 1,342评论 2 0
  • 起步,然后三秒左转变道,然后在变道,换一档,直走准备左转,停下来观察,没车左转,有车停一停等,过到去摆直车身,直线...
    旭锋蜀黍阅读 137评论 0 0