大雅的数组降维,javascript读书笔记

by admin on 2019年4月23日

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

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

原稿出处:
ralph_zhu   

将多维数组(越发是二维数组)转化为壹维数组是专门的学问支付中的常用逻辑,除了利用节约能源的轮回转变以外,我们还足以动用Javascript的语言特征落成更精简优雅的转移。本文将从节俭的循环转变起始,逐一介绍三种常用的转变方法,并借此轻便回想Array.prototype.concat方法和Function.prototype.apply方法。
以下代码将以把贰维数组降维到1维数组为例。

  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;
}

此措施思路简单,利用再度循环遍历2维数组中的每一个成分并置于新数组中。

 

  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方法的参数是3个因素,该因素会被直接插入到新数组中;借使参数是1个数组,该数组的11要素将被插入到新数组中;将该天性应用到代码中:

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方法的参数,数组中的每1个子元素又都会被单独插入进新数组。
利用concat方法,我们将再也循环简化为了单重循环。

 

  1. 利用apply和concat转换
    依照常规,先来回看一下MDN上对于apply方法的牵线:
    大雅的数组降维,javascript读书笔记。“The apply() method calls a function with a given this value and
    arguments provided as an array.”

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

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

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

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

读者也可参看本文思路,自己行使递归落成N维数组降维的逻辑。

3 赞 8 收藏
评论

必发88 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;
}

二.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],随机的选项三个与数组最终1项交流。第三遍巡回,[0,8],与数组的倒数第三项交流。
  return target;
}

三.数组的平坦化管理:flatten,再次回到三个1维数组

复制代码 代码如下:

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

四.unique方式:对数组去重操作

此方法,面试官最开心问了,因为它有各样兑现方式,最普通的是多少个for循环。一般精晓的最多的是利用一个目的a,然后多少个for循环数组arr,每一次if(a[arr[大雅的数组降维,javascript读书笔记。i]])是或不是留存,不存在则push到您新定义的数组result中。存在就认证,重复,由此不要push到result中。那种方案,针对”12三”,1二三,会感到一样的,其实一个是字符串,贰个是数字,不该以为是壹致的。

就此就涌出了以下办法:[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];
}

//首先判定项目是不是1律,假如一样,就判别他们的值是还是不是等于,不等于就存进去,相等就印证此前已经存在那几个值了。

万1类型分歧,那里存在三种状态,

第二种意况,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:二}, b ={贰:一};

首先次巡回时,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 一;else return -一;},A.sort(compare).

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

7.unshift在ie陆,7下不回去数老总度。

复制代码 代码如下:

if([].unshift(1)!==一)  
//往空数组中从目前增添一项,别的浏览器会回来1,而IE陆,7不会回去数总监度。那时就实践if语句
{
  var _unshift = Array.prototype.unshift;      //函数勒迫。
  Array.prototype.unshift = function(){
    _unshift.apply(this,arguments);
    return this.length;
  }
}

八.splice在1个参数的意况下,IE八以及以下版本私下认可第3个参数为0,而任何浏览器是数老板度。

复制代码 代码如下:

if([1,2,3].splice(1).length == 0)  
//IE8以及以下版本会等于0,别的版本会等于三,进入if里面
{
  var _splice = Array.prototype.splice;
  Array.prototype.splice = function(a){
    if(arguments.length == 一)   //如若唯有一个参数时
    {
      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的区分,重回值,以及对原数组的影响。

以上便是本节的剧情的精简版了,就算简单,但根本都在,希望对我们阅读本节的时候能享有协助

壹.indexOf和lastIndexOf方法:
因为IE7在数组对象上采取indexOf会报错,所以须要…

[Ctrl+A 全选
注:如需引进外部Js需刷菜鸟艺实行]

因为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;
}

//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;
}

贰.shuffle艺术:对数组实行洗牌。

jQuery对象是用来存款和储蓄与拍卖dom元素的,它根本依附于setArray方法来安装与保险长度与索引,而setArray的参数需求是1个数组,因而makeArray的地位12分首要。那办法保险固然未有参数也要回来多少个空数组。
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]必发88,,随机的选项一个与数组最终1项调换。第叁次巡回,[0,8],与数组的尾数第2项交流。
  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,再次来到3个壹维数组

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艺术:对数组去重操作

Ext的toArray方法

此措施,面试官最喜爱问了,因为它有二种得以达成方式,最平凡的是四个for循环。一般通晓的最多的是行使三个目的a,然后二个for循环数组arr,每便if(a[arr[i]])是或不是留存,不存在则push到你新定义的数组result中。存在就印证,重复,由此不要push到result中。那种方案,针对”1二三”,1二叁,会以为一样的,其实二个是字符串,多个是数字,不该感到是1律的。

复制代码 代码如下:

从而就应运而生了以下情势:[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);
}
}()

复制代码 代码如下:

Ext的规划相比神奇,作用也相比较强硬。它一同初就机关实行本人,未来就绝不判别浏览器了。它还有多少个可选参数,对转移的纯数组开始展览操作。
最后看dojo的_toArray,dojo的贯彻连接那么奇异的。
和Ext同样,后边五个参数是可选,只可是第四个是偏移量,最终2个是已有的数组,用于把新生的新组成分合并过去。

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

复制代码 代码如下:

//首先剖断项目是或不是一样,假诺1致,就剖断他们的值是不是等于,不对等就存进去,相等就表明从前曾经存在那么些值了。

(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类数组对象调换为数组对象的点子实例分析

第2种情形,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
= {一:二}, b ={贰: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;

这种情景下,就会冒出全体的对象,都只会存最终2个对象值。

当思念对象时,小编就会采取以下那种措施:

复制代码 代码如下:

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;

伍.数组排序:sort方法,假设要排序的是目标,能够友善写2个compare(a,b){if(a.age>b.age)
return 一;else return -一;},A.sort(compare).

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

7.unshift在ie陆,七下不回来数主任度。

复制代码 代码如下:

if([].unshift(1)!==一)  
//往空数组中从后边增添一项,别的浏览器会回来1,而IE六,七不会回去数老总度。那时就奉行if语句
{
  var _unshift = Array.prototype.unshift;      //函数恫吓。
  Array.prototype.unshift = function(){
    _unshift.apply(this,arguments);
    return this.length;
  }
}

8.splice在3个参数的事态下,IE八以及以下版本暗中认可第一个参数为0,而其余浏览器是数老董度。

复制代码 代码如下:

if([1,2,3].splice(一).length == 0)  
//IE捌以及以下版本会等于0,其余版本会等于三,进入if里面
{
  var _splice = Array.prototype.splice;
  Array.prototype.splice = function(a){
    if(arguments.length == 一)   //倘若唯有三个参数时
    {
      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框架规划之框架分类及主要效用
  • 2014年最抢手的二一款JavaScript框架推荐
  • javascript框架规划读书笔记之字符串的扩充和修补
  • javascript框架企划读书笔记之模块加载系统
  • javascript框架统一妄图读书笔记之种子模块
  • JavaScript框架(iframe)操作总括
  • 怎么取舍Javascript框架(Javascript
    Framework)
  • 详见介绍八款超实用JavaScript框架
  • brook javascript框架介绍
  • 十多个最盛行的JavaScript框架[推荐]
  • 怎么样挑选符合您的JavaScript框架

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图