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 相关文章推荐
把jquery 的dialog和ztree结合实现步骤
Aug 02 Javascript
jQuery prev ~ siblings选择器使用介绍
Aug 09 Javascript
javascript HTML5文件上传FileReader API
Mar 27 Javascript
关于Jquery中的事件绑定总结
Oct 26 Javascript
如何用JS/HTML将时间戳转换为“xx天前”的形式
Feb 06 Javascript
Vue2.0如何发布项目实战
Jul 27 Javascript
layer实现登录弹框,登录成功后关闭弹框并调用父窗口的例子
Sep 11 Javascript
js 判断当前时间是否处于某个一个时间段内
Sep 19 Javascript
Vue 实现html中根据类型显示内容
Oct 28 Javascript
Vue实现腾讯云点播视频上传功能的实现代码
Aug 17 Javascript
Jquery 获取相同NAME 或者id删除行操作
Aug 24 jQuery
jQuery实现简单全选框
Sep 13 jQuery
关于图片按比例自适应缩放的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
PHP个人网站架设连环讲(三)
2006/10/09 PHP
文件上传之SWFUpload插件(代码)
2015/07/30 PHP
prototype Element学习笔记(Element篇三)
2008/10/26 Javascript
javascript中关于执行环境的杂谈
2011/08/14 Javascript
JavaScript单元测试ABC
2012/04/12 Javascript
JS实现模仿微博发布效果实例代码
2013/12/16 Javascript
js中Math之random,round,ceil,floor的用法总结
2013/12/26 Javascript
纯js实现倒计时功能
2017/01/06 Javascript
使用ionic在首页新闻中应用到的跑马灯效果的实现方法
2017/02/13 Javascript
nodeJS实现路由功能实例代码
2017/06/08 NodeJs
Vue自定义toast组件的实例代码
2018/08/15 Javascript
vue实现动态给id赋值,点击事件获取当前点击的元素的id操作
2020/11/09 Javascript
node.js 基于 STMP 协议和 EWS 协议发送邮件
2021/02/14 Javascript
使用python遍历指定城市的一周气温
2017/03/31 Python
Python中定时任务框架APScheduler的快速入门指南
2017/07/06 Python
python记录程序运行时间的三种方法
2017/07/14 Python
详解Python 实现元胞自动机中的生命游戏(Game of life)
2018/01/27 Python
Python+pandas计算数据相关系数的实例
2018/07/03 Python
只需7行Python代码玩转微信自动聊天
2019/01/27 Python
ubuntu 16.04下python版本切换的方法
2019/06/14 Python
在Python中获取操作系统的进程信息
2019/08/27 Python
Python实现微信机器人的方法
2019/09/06 Python
解决pycharm启动后总是不停的updating indices...indexing的问题
2019/11/27 Python
利用matplotlib实现根据实时数据动态更新图形
2019/12/13 Python
Pytorch之保存读取模型实例
2019/12/30 Python
python实现五子棋游戏(pygame版)
2020/01/19 Python
Jupyter Notebook 远程访问配置详解
2021/01/11 Python
css3媒体查询中device-width和width的区别详解
2020/03/27 HTML / CSS
皮尔·卡丹巴西官方商店:Pierre Cardin
2017/07/21 全球购物
澳大利亚领先的皮肤诊所:Skin Matrix(抗衰老、痤疮专家、药妆护肤)
2018/05/20 全球购物
土耳其风格手工珠宝:Ottoman Hands
2019/07/26 全球购物
公司处罚决定书
2015/06/24 职场文书
浅谈MySQL next-key lock 加锁范围
2021/06/07 MySQL
nginx结合openssl实现https的方法
2021/07/25 Servers
Python Pandas解析读写 CSV 文件
2022/04/11 Python
Python中的 No Module named ***问题及解决
2022/07/23 Python