您的位置:新葡亰496net > 新葡亰官网 > 新葡亰496net:javascript框架企划读书笔记之数组的

新葡亰496net:javascript框架企划读书笔记之数组的

发布时间:2019-06-21 08:36编辑:新葡亰官网浏览(62)

    优雅的数组降维——Javascript中apply方法的妙用

    2016/02/18 · JavaScript · apply, 数组

    原版的书文出处: ralph_zhu   

    将多维数组(尤其是二维数组)转化为一维数组是事情耗费中的常用逻辑,除了采用节约能源的循环转变以外,大家还是能行使Javascript的言语特色达成更为精简优雅的转变。本文将从节约的大循环转变开首,逐个介绍二种常用的转变方法,并借此轻巧回看Array.prototype.concat方法和Function.prototype.apply方法。
    以下代码将以把二维数组降维到一维数组为例。

    1. 仔细的转移

    JavaScript

    function reduceDimension(arr) { var reduced = []; for (var i = 0; i < arr.length; i ) { for (var j = 0; j < arr[i].length; j ) { reduced.push(arr[i][j]); } } return reduced; }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function reduceDimension(arr) {
        var reduced = [];
        for (var i = 0; i < arr.length; i ) {
            for (var j = 0; j < arr[i].length; j ) {
                reduced.push(arr[i][j]);
            }
        }
        return reduced;
    }

    此办法思路轻易,利用再度循环遍历二维数组中的每一个元素并放置新数组中。

     

    1. 利用concat转换
      先来回看一下MDN上对于该措施的介绍:
      “concat creates a new array consisting of the elements in the object on which it is called, followed in order by, for each argument, the elements of that argument (if the argument is an array) or the argument itself (if the argument is not an array).”

    即如若concat方法的参数是三个成分,该因素会被直接插入到新数组中;假如参数是二个数组,该数组的逐条要素将被插入到新数组中;将该天性应用到代码中:

    JavaScript

    function reduceDimension(arr) { var reduced = []; for (var i = 0; i < arr.length; i ){ reduced = reduced.concat(arr[i]); } return reduced; }

    1
    2
    3
    4
    5
    6
    7
    function reduceDimension(arr) {
        var reduced = [];
        for (var i = 0; i < arr.length; i ){
            reduced = reduced.concat(arr[i]);
        }
        return reduced;
    }

    arr的每二个因素都是叁个数组,作为concat方法的参数,数组中的每贰个子成分又都会被单独插入进新数组。
    动用concat方法,大家将再也循环简化为了单重循环。

     

    1. 利用apply和concat转换
      遵照规矩,先来回看一下MDN上对此apply方法的牵线:
      “The apply() method calls a function with a given this value and arguments provided as an array.”

    即apply方法会调用二个函数,apply方法的首先个参数会作为被调用函数的this值,apply方法的首个参数(三个数组,或类数组的目的)会作为被调用对象的arguments值,也正是说该数组的逐条要素将会相继成为被调用函数的一一参数;将该天性应用到代码中:

    function reduceDimension(arr) { return Array.prototype.concat.apply([], arr); }

    1
    2
    3
    function reduceDimension(arr) {
        return Array.prototype.concat.apply([], arr);
    }

    arr作为apply方法的第一个参数,本人是叁个数组,数组中的每二个要素(依旧数组,即二维数组的第二维)会被看做参数依次传入到concat中,效果同样[].concat([1,2], [3,4], [5,6])。
    使用apply方法,大家将单重循环优化为了一行代码,很简短有型有木有啊~

    读者也可参照本文思路,本中国人民银行使递归达成N维数组降维的逻辑。

    3 赞 8 收藏 评论

    新葡亰496net 1

    在行业内部浏览器中,好像只要对象存在length属性,就能够把它调换为数组,但IE就不尽然。

    1.indexOf和lastIndexOf方法:

    javascript框架安插读书笔记之数组的扩大与修复,javascript读书笔记

    1.indexOf和lastIndexOf方法:

    因为IE7在数组对象上使用indexOf会报错,所以需求重写二个包容性的。

    复制代码 代码如下:

    Array.prototype.lastIndexOf(item,index){
      var n = this.length,i = (index==null||index>n-1)?n-1:index;
      if(i < 0) i = n i;
      for(;i>=0;i--)
        if(this[i] === item)   //全等剖断,indexOf,lastIndexOf
          return i;
      return -1;
    }

    2.shuffle方法:对数组实行洗牌。

    复制代码 代码如下:

    function shuffle(target){
      var i = target.length, j ,temp;
      for(;i>0;j=parseInt(Math.random() * i), x = target[--i],target[i] = target[j],target[j]=x){}   
         //假设length=10,那么Math.random()*10->[0,10),parseInt后,[0,9],随机的选料一个与数组最终一项沟通。第三回巡回,[0,8],与数组的倒数第二项交换。
      return target;
    }

    3.数组的平坦化管理:flatten,重返二个一维数组

    复制代码 代码如下:

    function flatten(arr){
      var result = [];
      arr.forEach(function(item){
        if(Array.isArray(item))   result.concat(flatten(item));
        else  result.push(item);
      });
      return result;
    }

    4.unique措施:对数组去重操作

    此措施,面试官最高兴问了,因为它有多样落到实处情势,最家常的是七个for循环。一般驾驭的最多的是应用二个指标a,然后二个for循环数组arr,每一次if(a[arr[i]])是不是留存,不设有则push到您新定义的数组result中。存在就评释,重复,由此不要push到result中。这种方案,针对"123",123,会以为一样的,其实二个是字符串,三个是数字,不该以为是平等的。

    为此就涌出了以下格局:[1,"1","1"]

    复制代码 代码如下:

     if ((typeof obj[array[i]]) != (typeof array[i]) || obj[array[i]] != array[i]) {
      a.push(array[i]);
      obj[array[i]] = array[i];
    }

    //首先决断项目是不是同样,假使同样,就判定他们的值是不是等于,不等于就存进去,相等就认证以前已经存在那些值了。

    假设类型不平等,这里存在三种状态,

    首先种意况,obj以前曾经存了此数额了,比方:obj[123] = 123,现在array[i] = "123",这时,typeof obj[array[i]])是数字,而typeof array[i]是字符串,由此存入数组中。

    第三种情况是obj还没存此数据,例如:array[i] = "123",obj["123"] = undefind,这时typeof obj[array[i]])就是typeof undefined = undefined,不等于typeof array[i],存入数组中。

    此种方法,能够消除字符串和数字同样的图景,可是力不从心缓慢解决对象同样的景况。举例:a = {1:2}, b ={2:1};

    率先次巡回时,typeof obj[a] = undefined,typeof a = Object。存入obj[a] =a.其实正是obj[Object] = a;

    其次次巡回时,typeof obj[b] 等于typeof obj[Object]事实上便是typeof a = object,typeof b = object.因而进入到obj[array[i]] != array[i]|,也就是obj[b]->obj[Object]->a != b,因而存入

    obj[b] = b;也就是obj[Object] = b;覆盖了前头的obj[Object] = a;

    这种情状下,就能产出全部的对象,都只会存最终二个目的值。

    当思念对象时,笔者就能够利用以下这种措施:

    复制代码 代码如下:

    for(var i = 0; i < temp.length; i ){
                    for(var j = i 1; j < temp.length; j ){
                            if(temp[i] === temp[j]){
                                    temp.splice( j, 1 );
                                    j--;
                            }
                    }
            }
     return temp;

    5.数组排序:sort方法,假若要排序的是目的,能够自身写三个compare(a,b){if(a.age>b.age) return 1;else return -1;},A.sort(compare).

    6.min回去数组最小值:return Math.min.apply(0,array);

    7.unshift在ie6,7下不回来数主任度。

    复制代码 代码如下:

    if([].unshift(1)!==1)   //往空数组中往日方增多一项,别的浏览器会重回1,而IE6,7不会回来数主任度。那时就施行if语句
    {
      var _unshift = Array.prototype.unshift;      //函数威迫。
      Array.prototype.unshift = function(){
        _unshift.apply(this,arguments);
        return this.length;
      }
    }

    8.splice在二个参数的情况下,IE8以及以下版本私下认可第一个参数为0,而其余浏览器是数首席营业官度。

    复制代码 代码如下:

    if([1,2,3].splice(1).length == 0)   //IE8以及以下版本会等于0,其他版本会等于3,进入if里面
    {
      var _splice = Array.prototype.splice;
      Array.prototype.splice = function(a){
        if(arguments.length == 1)   //借使唯有多个参数时
        {
          return _splice.call(this,a,this.length);
        }else{
          return _splice.apply(this,arguments);
        }
      }
    }

    其一方法会更动数组的选项,因而数组的push,pop,shift,unshift(那些主意也会修改数组的取舍)都会调用那些方法来完结。

    此间有三个地点须要专注:

    复制代码 代码如下:

    var color = new Array('red','blue','yellow','black');
    var color2 = color.splice(2,0,'brown','pink');
    alert(color); // red,blue,brown,pink,yellow,black,在yellow选项上,开始操作,假诺剔除为0,则增加的挑三拣四是在yellow从前插入。切记。

     
    此处请大家去看下splice和slice的界别,重回值,以及对原数组的震慑。

    上述正是本节的内容的精简版了,固然轻便,但要害都在,希望对大家阅读本节的时候能抱有支持

    1.indexOf和lastIndexOf方法: 因为IE7在数组对象上选拔indexOf会报错,所以必要...

    在规范浏览器中,好像只要对象存在length属性,就能够把它转变为数组,但IE就不尽然。

    [Ctrl A 全选 注:如需引入外界Js需刷新能力举办]

    因为IE7在数组对象上采纳indexOf会报错,所以要求重写多少个包容性的。

    [Ctrl A 全选 注:如需引进外部Js需刷新手艺实践]

    随后大家看看各大类库的拍卖:

    复制代码 代码如下:

    紧接着我们看看各大类库的管理:

    复制代码 代码如下:

    Array.prototype.lastIndexOf(item,index){
      var n = this.length,i = (index==null||index>n-1)?n-1:index;
      if(i < 0) i = n i;
      for(;i>=0;i--)
        if(this[i] === item)   //全等看清,indexOf,lastIndexOf
          return i;
      return -1;
    }

    复制代码 代码如下:

    //jQuery的makeArray
    var makeArray = function( array ) {
    var ret = [];
    if( array != null ){
    var i = array.length;
    // The window, strings (and functions) also have 'length'
    if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )
    ret[0] = array;
    else
    while( i )
    ret[--i] = array[i];
    }
    return ret;
    }

    2.shuffle措施:对数组举行洗牌。

    //jQuery的makeArray
    var makeArray = function( array ) {
    var ret = [];
    if( array != null ){
    var i = array.length;
    // The window, strings (and functions) also have 'length'
    if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )
    ret[0] = array;
    else
    while( i )
    ret[--i] = array[i];
    }
    return ret;
    }

    jQuery对象是用来囤积与拍卖dom成分的,它首要借助于setArray方法来设置与保卫安全长度与索引,而setArray的参数须要是二个数组,由此makeArray的身价拾分关键。那情势保障就算未有参数也要回到三个空数组。
    Prototype.js的$A方法

    复制代码 代码如下:

    jQuery对象是用来囤积与管理dom成分的,它首要借助于setArray方法来安装与爱护长度与索引,而setArray的参数供给是一个数组,因而makeArray的身价十分重大。那格局有限支撑固然未有参数也要再次回到一个空数组。
    Prototype.js的$A方法

    复制代码 代码如下:

    function shuffle(target){
      var i = target.length, j ,temp;
      for(;i>0;j=parseInt(Math.random() * i), x = target[--i],target[i] = target[j],target[j]=x){}   
         //假设length=10,那么Math.random()*10->[0,10),parseInt后,[0,9],随机的取舍一个与数组最后一项调换。第二次巡回,[0,8],与数组的尾数第二项沟通。
      return target;
    }

    复制代码 代码如下:

    function $A(iterable) {
    if (!iterable) return [];
    if (iterable.toArray) return iterable.toArray();
    var length = iterable.length || 0, results = new Array(length);
    while (length--) results[length] = iterable[length];
    return results;
    }

    3.数组的平坦化处理:flatten,重返贰个一维数组

    function $A(iterable) {
    if (!iterable) return [];
    if (iterable.toArray) return iterable.toArray();
    var length = iterable.length || 0, results = new Array(length);
    while (length--) results[length]新葡亰496net:javascript框架企划读书笔记之数组的强大与修补,js将类数组对象调换来数组对象。 = iterable[length];
    return results;
    }

    mootools的$A方法

    复制代码 代码如下:

    mootools的$A方法

    复制代码 代码如下:

    function flatten(arr){
      var result = [];
      arr.forEach(function(item){
        if(Array.isArray(item))   result.concat(flatten(item));
        else  result.push(item);
      });
      return result;
    }

    复制代码 代码如下:

    function $A(iterable){
    if (iterable.item){
    var l = iterable.length, array = new Array(l);
    while (l--) array[l] = iterable[l];
    return array;
    }
    return Array.prototype.slice.call(iterable);
    };

    4.unique主意:对数组去重操作

    function $A(iterable){
    if (iterable.item){
    var l = iterable.length, array = new Array(l);
    while (l--) array[l] = iterable[l];
    return array;
    }
    return Array.prototype.slice.call(iterable);
    };

    Ext的toArray方法

    此方法,面试官最喜爱问了,因为它有各类兑现情势,最平日的是多少个for循环。一般了解的最多的是应用三个目的a,然后四个for循环数组arr,每趟if(a[arr[i]])是还是不是存在,不设有则push到您新定义的数组result中。存在就注明,重复,由此不用push到result中。这种方案,针对"123",123,会感觉同样的,其实一个是字符串,贰个是数字,不应该感到是同样的。

    Ext的toArray方法

    复制代码 代码如下:

    因此就出现了以下措施:[1,"1","1"]

    复制代码 代码如下:

    var toArray = function(){
    return isIE ?
    function(a, i, j, res){
    res = [];
    Ext.each(a, function(v) {
    res.push(v);
    });
    return res.slice(i || 0, j || res.length);
    } :
    function(a, i, j){
    return Array.prototype.slice.call(a, i || 0, j || a.length);
    }
    }()

    复制代码 代码如下:

    var toArray = function(){
    return isIE ?
    function(a, i, j, res){
    res = [];
    Ext.each(a, function(v) {
    res.push(v);
    });
    return res.slice(i || 0, j || res.length);
    } :
    function(a, i, j){
    return Array.prototype.slice.call(a, i || 0, j || a.length);
    }
    }()

    Ext的规划相比较神奇,成效也比较强硬。它一起始就自行试行自己,以后就毫无判别浏览器了。它还应该有四个可选参数,对转移的纯数组开始展览操作。
    最后看dojo的_toArray,dojo的兑现再而三那么奇异的。 和Ext相同,前面多个参数是可选,只可是第三个是偏移量,最终二个是已有的数组,用于把新生的新组成分合併过去。

     if ((typeof obj[array[i]]) != (typeof array[i]) || obj[array[i]] != array[i]) {
      a.push(array[i]);
      obj[array[i]] = array[i];
    }

    Ext的统一打算比较玄妙,功效也正如强硬。它一开端就活动实践本身,今后就毫无判断浏览器了。它还恐怕有五个可选参数,对转移的纯数组进行操作。
    最后看dojo的_toArray,dojo的达成连接那么奇异的。 和Ext同样,后边五个参数是可选,只不过第二个是偏移量,最终一个是已部分数组,用于把新生的新组成分合併过去。

    复制代码 代码如下:

    //首先判别项目是或不是同样,假若一样,就决断他们的值是或不是等于,不等于就存进去,相等就认证在此之前已经存在那一个值了。

    复制代码 代码如下:

    (function(){
    var efficient = function(obj, offset, startWith){
    return (startWith||[]).concat(Array.prototype.slice.call(obj, offset||0));
    };
    var slow = function(obj, offset, startWith){
    var arr = startWith||[];
    for(var x = offset || 0; x >obj.length; x ){
    arr.push(obj[x]);
    }
    return arr;
    };
    dojo._toArray =
    dojo.isIE ? function(obj){
    return ((obj.item) ? slow : efficient).apply(this, arguments);
    } :
    efficient;
    })();

    如果类型差异等,这里存在二种意况,

    (function(){
    var efficient = function(obj, offset, startWith){
    return (startWith||[]).concat(Array.prototype.slice.call(obj, offset||0));
    };
    var slow = function(obj, offset, startWith){
    var arr = startWith||[];
    for(var x = offset || 0; x >obj.length; x ){
    arr.push(obj[x]);
    }
    return arr;
    };
    dojo._toArray =
    dojo.isIE ? function(obj){
    return ((obj.item) ? slow : efficient).apply(this, arguments);
    } :
    efficient;
    })();

    您只怕感兴趣的稿子:

    • JavaScript中的类数组对象介绍
    • JavaScript 里的类数组对象
    • js 用于检查评定类数组对象的函数方法
    • JQuery $.each遍历JavaScript数组对象实例
    • js使用Array.prototype.sort()对数组对象排序的措施
    • js接收并转载Java中的数组对象的必定要经过的地方
    • JS从非数组对象转数组的法子小结
    • javascript Array数组对象的扩张函数代码
    • JavaScript类数组对象调换为数组对象的法门实例解析

    先是种情况,obj以前早就存了此数据了,举例:obj[123] = 123,现在array[i] = "123",这时,typeof obj[array[i]])是数字,而typeof array[i]是字符串,因而存入数组中。

    [Ctrl A 全选 注:如需引进外界Js需刷新技能实施] 接着我...

    第三种情形是obj还没存此数据,举例:array[i]新葡亰496net, = "123",obj["123"] = undefind,这时typeof obj[array[i]])就是typeof undefined = undefined,不等于typeof array[i],存入数组中。

    此种方法,能够解决字符串和数字同样的意况,可是力不从心缓和对象同样的情景。比方:a = {1:2}, b ={2:1};

    先是次巡回时,typeof obj[a] = undefined,typeof a = Object。存入obj[a] =a.其实正是obj[Object] = a;

    其次次巡回时,typeof obj[b] 等于typeof obj[Object]实则就是typeof a = object,typeof b = object.由此进入到obj[array[i]] != array[i]|,也就是obj[b]->obj[Object]->a != b,由此存入

    obj[b] = b;也就是obj[Object] = b;覆盖了事先的obj[Object] = a;

    这种景况下,就能产出全部的对象,都只会存最后二个对象值。

    当考虑对象时,作者就能接纳以下这种方法:

    复制代码 代码如下:

    for(var i = 0; i < temp.length; i ){
                    for(var j = i 1; j < temp.length; j ){
                            if(temp[i] === temp[j]){
                                    temp.splice( j, 1 );
                                    j--;
                            }
                    }
            }
     return temp;

    5.数组排序:sort方法,假设要排序的是指标,能够和煦写贰个compare(a,b){if(a.age>b.age) return 1;else return -1;},A.sort(compare).

    6.min再次来到数组最小值:return Math.min.apply(0,array);

    7.unshift在ie6,7下不回去数高管度。

    复制代码 代码如下:

    if([].unshift(1)!==1)   //往空数组中从眼下增添一项,其余浏览器会回来1,而IE6,7不会回去数CEO度。那时就施行if语句
    {
      var _unshift = Array.prototype.unshift;      //函数威吓。
      Array.prototype.unshift = function(){
        _unshift.apply(this,arguments);
        return this.length;
      }
    }

    8.splice在四个参数的情形下,IE8以及以下版本默许第贰个参数为0,而其它浏览器是数老董度。

    复制代码 代码如下:

    if([1,2,3].splice(1).length == 0)   //IE8以及以下版本会等于0,别的版本会等于3,进入if里面
    {
      var _splice = Array.prototype.splice;
      Array.prototype.splice = function(a){
        if(arguments.length == 1)   //假如唯有三个参数时
        {
          return _splice.call(this,a,this.length);
        }else{
          return _splice.apply(this,arguments);
        }
      }
    }

    其一方法会改动数组的选项,因此数组的push,pop,shift,unshift(那一个措施也会修改数组的选项)都会调用那一个方法来落到实处。

    这里有一个地点要求专注:

    复制代码 代码如下:

    var color = new Array('red','blue','yellow','black');
    var color2 = color.splice(2,0,'brown','pink');
    alert(color); // red,blue,brown,pink,yellow,black,在yellow选项上,起始操作,假诺除去为0,则拉长的挑选是在yellow在此以前插入。切记。

     
    那边请大家去看下splice和slice的界别,重临值,以及对原数组的熏陶。

    如上正是本节的源委的精简版了,纵然简单,但要害都在,希望对我们阅读本节的时候能具有辅助

    您恐怕感兴趣的小说:

    • 十大火爆的JavaScript框架和库
    • 深切分析JavaScript框架Backbone.js中的事件机制
    • JavaScript框架是怎么?如何技巧叫做框架?
    • 超赞的动手成立JavaScript框架的详尽教程
    • javascript框架设计等等工厂
    • javascript框架企划之浏览器的嗅探和特性侦测
    • javascript框架规划之种子模块
    • javascript框架企划之框架分类及第一成效
    • 二零一五年最看好的21款JavaScript框架推荐
    • javascript框架企划读书笔记之字符串的扩张和修补
    • javascript框架规划读书笔记之模块加载系统
    • javascript框架企划读书笔记之种子模块
    • JavaScript框架(iframe)操作总括
    • 怎么选拔Javascript框架(Javascript Framework)
    • 详见介绍8款超实用JavaScript框架
    • brook javascript框架介绍
    • 17个最流行的JavaScript框架[推荐]
    • 怎么样抉择切合您的JavaScript框架

    本文由新葡亰496net发布于新葡亰官网,转载请注明出处:新葡亰496net:javascript框架企划读书笔记之数组的

    关键词: