JavaScript Array Flatten 与递归使用介绍_javascript技巧

如何用 JavaScript 将 [1,2,3,[4,5, [6,7]], [[[8]]]] 这样一个 Array 变成 [1,2,3,4,5, 6,7,8] 呢?传说中的 Array Flatten。

处理这种问题,通常我们会需要递归,来让程序自己按照一种算法去循环。在某书说写着,“递归是一种强大的编程技术”,好吧,她不仅仅属于 JavaScript。递归可以很难,也可以比较简单(总得来说还是比较难)。处理上面这个问题,用递归来解决,应该是比较适合的。之前工友这样实现了,算是一个简单的递归使用实例吧:

复制代码 代码如下:

flatten: function(ac){
var array = [];
var group = this.arr;
if(ac) group = ac;
for (var i = 0; i < group.length; i++){
if(group[i] instanceof Array){
array = array.concat(this.flatten(group[i]));
}else{
array = array.concat(group[i]);
}
}
return array;
}

在 if(group[i] instanceof Array) 的时候,调用函数自身,通过传参数的形式进行递归。只是在重构 Array.js 的时候,就觉得既然是框架,那么多抽象出来的东西不用,是不是太浪费了。所以,最好调用已经抽象出来的静态函数,而不是又重新一遍。这里有 for 循环,也就是说我们会需要有 each。结果呢?四个字,不好实现。因为我们始终要创建一个数组,最终 return 这个新的数组,得重新抽出来一个函数来调。这不就违背了初衷?

网上瞄了一下,最终盯在 prototype 上。他的实现方法是抽象出一个处理递归增量的函数,再利用这个函数来做递归。怎么说呢?想说,这就叫框架。下面是一个处理递归的函数:

复制代码 代码如下:

function inject(memo, iterator, context) {
this.each(function(value, index) {
memo = iterator.call(context, memo, value, index);
});
return memo;
}

而这个 flatten 函数,最终的实现是这样的,这代码真漂亮:

复制代码 代码如下:

function flatten() {
return this.inject([], function(array, value) {
if (Object.isArray(value))
return array.concat(value.flatten());
array.push(value);
return array;
});
}

当然,这里面还需要另外一个抽象出来的函数,来处理 for 循环,就是我们的 each 函数了。顺路在 flatten 中,带出这个 each 函数吧,学习了 jQuery 的做法,加入原生支持;当然,还可以处理纯对象,而不仅仅是数组:

复制代码 代码如下:

each: function (callback, bind) {
var isObject = arale.typeOf(this.obj) === 'object',
i = 0,
key;

if (isObject) {
var obj = this.obj;
for (key in obj) {
if (callback.call(bind, key, obj[key]) === false) {
break;
}
}
} else {
var arr = this.obj;
if (Array.prototype.forEach) {

// 用户 return false; 的时候还会继续执行
// 原生的很囧,去还是舍呢? marked TODO;
return [].forEach.call(arr, callback, bind);
};
for (var value = arr[0], length = arr.length; i < length && callback.call(bind, i, value) !== false; value = arr[++i]) {};
}
}

最近玩 Javascript 比较多。瞄了一下最近的文章,还有在团队内部博客上发的文章,全都是 JS的。囧。似乎是一个很大的改变。需要平衡一下了。

时间: 2024-10-21 13:41:44

JavaScript Array Flatten 与递归使用介绍_javascript技巧的相关文章

JavaScript中setter和getter方法介绍_javascript技巧

javascript中的setter.getter是平时接触比较少的方法,其本身也并不是标准方法,只在非ie浏览器里支持(ie内核也许有其他方法可以做到呢?暂时不知其解),但是加以利用可以做许多事情,比如: 1.对数据的访问限制: a.value是对value变量的getter方法调用,如果在getter方法实现中抛出异常,可以阻止对value变量的访问 2.对dom变量进行监听: window.name是一个跨域非常好用的dom属性(大名鼎鼎,详见百度),如果覆盖window.name的set

浅析JavaScript Array和string的转换(推荐)_javascript技巧

Array类可以如下定义: var aValues = new Array();  如果预先知道数组的长度,可以用参数传递长度 var aValues = new Array(20);  ------------------如下2种定义方式是一样的--------1------- var aColors = new Array(); aColors[0] = "red"; aColors[1] = "green"; aColors[2] = "blue&q

js中array的sort()方法使用介绍_javascript技巧

或许你一直在用javascript中的array的sort. 或许你一直相信它会给你正确的结果. 至少我曾经也是这样认为的,直到有一天,我看到了如下的代码 : 复制代码 代码如下: [5,10,1].sort(); 或许结果有点出人意料.结果如下: 复制代码 代码如下: [1,10,5] 仔细深究之后,发现原来默认的sort方法并不是按照整形数据来排序,而是用的字符串匹配方式. 换言之就是10 中的这个 1 导致了上面代码的错误. 当然,解决方法有很多,可以给sort方法中传入回调函数. 复制代

javascript简单事件处理和with用法介绍_javascript技巧

这一期介绍一些简单的事件处理: 1.鼠标点击 复制代码 代码如下: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title> New Document </title> <meta name="Gene

JavaScript中的类数组对象介绍_javascript技巧

JavaScript中,数组是一个特殊的对象,其property名为正整数,且其length属性会随着数组成员的增减而发生变化,同时又从Array构造函数中继承了一些用于进行数组操作的方法.而对于一个普通的对象来说,如果它的所有property名均为正整数,同时也有相应的length属性,那么虽然该对象并不是由Array构造函数所创建的,它依然呈现出数组的行为,在这种情况下,这些对象被称为"类数组对象".以下是一个简单的类数组对象: 复制代码 代码如下: var o = {0:42,

JavaScript中的Truthy和Falsy介绍_javascript技巧

与大多数编程语言一样,JavaScript中存在boolean类型,以供逻辑判断使用.不过,和很多其它编程语言不一样的是,JavaScript中存在Truthy值和Falsy值的概念 - 除了boolean值true.false外,所有类型的JavaScript值均可用于逻辑判断,其规则如下: 1.所有的Falsy值,当进行逻辑判断时均为false.Falsy值包括:false.undefined.null.正负0.NaN."". 2.其余所有的值均为Truthy,当进行逻辑判断时均为

JavaScript中的return语句简单介绍_javascript技巧

return语句在js中非常的重要,不仅仅具有返回函数值的功能,还具有一些特殊的用法,下面就结合实例简单介绍一下return语句的作用. 一.用来返回控制和函数结果: 通常情况,return语句对于一个函数是很有必要的,因为往往需要函数在一系列的代码执行后会得到一个期望的返回值,而此值就是通过return语句返回,并且将控制权返回给主调函数. 语法格式: return 表达式  代码实例如下: function add(){ var a=1; var b=2; return a+b; } fun

Javascript中的高阶函数介绍_javascript技巧

这是一个有趣的东西,这或许也在说明Javascript对象的强大.我们要做的就是在上一篇说到的那样,输出一个Hello,World,而输入的东西是print('Hello')('World'),而这就是所谓的高阶函数. 高阶函数 高阶看上去就像是一种先进的编程技术的一个深奥术语,一开始我看到的时候我也这样认为的. Javascript的高阶函数 然而,高阶函数只是将函数作为参数或返回值的函数.以上面的Hello,World作为一个简单的例子. 复制代码 代码如下: var Moqi = func

JavaScript中的值类型详细介绍_javascript技巧

计算机程序的实质很大程度上可以说是机器对各种信息(值)的操作与读写.在JavaScript中,存在多种类型的值,这些值分成两大类:Primitive(基本类型)和Object(对象). Primitive JavaScript中Primitive有5种类型: 1.Number.所有的数字,无论是整数还是小数,均为Number类型. 2.String.字符串类型. 3.Boolean.布尔类型,true或者false. 4.null.此类型只有null一个值. 5.undefined.此类型只有u