JavaScript Array Flatten 与递归使用介绍


Posted in Javascript onOctober 30, 2011

如何用 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的。?濉K坪跏且桓龊艽蟮母谋洹P枰?胶庖幌铝恕
Javascript 相关文章推荐
javascript 写类方式之二
Jul 05 Javascript
jQuery插件pagination实现无刷新分页
May 21 Javascript
angular.js分页代码的实例
Jul 27 Javascript
微信小程序开发之实现选项卡(窗口顶部TabBar)页面切换
Nov 25 Javascript
一个炫酷的Bootstrap导航菜单
Dec 28 Javascript
十大热门的JavaScript框架和库
Mar 21 Javascript
Bootstrap实现各种进度条样式详解
Apr 13 Javascript
canvas绘制爱心的几种方法总结(推荐)
Oct 31 Javascript
详解Vue路由钩子及应用场景(小结)
Nov 07 Javascript
微信小程序input框中加入小图标的实现方法
Jun 19 Javascript
vue模式history下在iis中配置流程
Apr 17 Javascript
微信小程序实现卡片左右滑动效果的示例代码
May 01 Javascript
关于图片按比例自适应缩放的js代码
Oct 30 #Javascript
js 弹出菜单/窗口效果
Oct 30 #Javascript
基于Jquery+Ajax+Json的高效分页实现代码
Oct 29 #Javascript
简单的前端js+ajax 购物车框架(入门篇)
Oct 29 #Javascript
分享一个自己写的table表格排序js插件(高效简洁)
Oct 29 #Javascript
Json2Template.js 基于jquery的插件 绑定JavaScript对象到Html模板中
Oct 29 #Javascript
基于jQuery的输入框在光标位置插入内容, 并选中
Oct 29 #Javascript
You might like
rrmdir php中递归删除目录及目录下的文件
2011/05/15 PHP
探讨:如何使用PHP实现计算两个日期间隔的年、月、周、日数
2013/06/13 PHP
PHP打印输出函数汇总
2016/08/28 PHP
JQuery自定义事件的应用 JQuery最佳实践
2010/08/01 Javascript
windows下安装nodejs及框架express
2015/08/07 NodeJs
Angular Js文件上传之form-data
2015/08/28 Javascript
AngularJS基础 ng-srcset 指令简单示例
2016/08/03 Javascript
ES6正则的扩展实例详解
2017/04/25 Javascript
JS设计模式之单例模式(一)
2017/09/29 Javascript
JavaScript自执行函数和jQuery扩展方法详解
2017/10/27 jQuery
nodejs实现大文件(在线视频)的读取
2020/10/16 NodeJs
vue按需加载组件webpack require.ensure的方法
2017/12/13 Javascript
Vue 将后台传过来的带html字段的字符串转换为 HTML
2018/03/29 Javascript
浅谈JS对象添加getter与setter的5种方法
2018/06/09 Javascript
React key值的作用和使用详解
2018/08/23 Javascript
详释JavaScript执行环境与执行栈
2019/04/02 Javascript
Vue的data、computed、watch源码浅谈
2020/04/04 Javascript
详解JavaScript 异步编程
2020/07/13 Javascript
[03:17]史诗级大片应援2018DOTA2国际邀请赛 致敬每一位坚守遗迹的勇士
2018/07/20 DOTA
Python实现截屏的函数
2015/07/26 Python
python 如何快速找出两个电子表中数据的差异
2017/05/26 Python
python字符串常用方法
2018/06/14 Python
对django views中 request, response的常用操作详解
2019/07/17 Python
创建Shapefile文件并写入数据的例子
2019/11/26 Python
Python进程间通信multiprocess代码实例
2020/03/18 Python
python 穷举指定长度的密码例子
2020/04/02 Python
pytorch读取图像数据转成opencv格式实例
2020/06/02 Python
CSS书写规范、顺序和命名规则
2014/03/06 HTML / CSS
英国珠宝钟表和家居礼品精品店:David Shuttle
2018/02/24 全球购物
简述Linux文件系统通过i节点把文件的逻辑结构和物理结构转换的工作过程
2012/04/17 面试题
销售人员自我评价怎么写
2013/09/19 职场文书
纪念一二九运动演讲稿
2014/09/16 职场文书
科学发展观标语
2014/10/08 职场文书
计划生育个人总结
2015/03/02 职场文书
python实现简单倒计时功能
2021/04/21 Python
go语言使用Casbin实现角色的权限控制
2021/06/26 Golang