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插件jTimer(jquery定时器)使用方法
Dec 23 Javascript
jquery插件validation实现验证身份证号等
Jun 04 Javascript
整理Javascript基础入门学习笔记
Nov 29 Javascript
jQuery使用$.ajax提交表单完整实例
Dec 11 Javascript
js实现prototype扩展的方法(字符串,日期,数组扩展)
Jan 14 Javascript
AngularJS入门(用ng-repeat指令实现循环输出
May 05 Javascript
详解webpack 入门总结和实践(按需异步加载,css单独打包,生成多个入口文件)
Jun 20 Javascript
BACKBONE.JS 简单入门范例
Oct 17 Javascript
浅谈vue单一组件下动态修改数据时的全部重渲染
Mar 01 Javascript
Vue.js子组件向父组件通信的方法实例代码详解
Dec 10 Javascript
JS实现判断有效的数独算法示例
Feb 25 Javascript
jQuery 实现扁平式小清新导航
Jul 07 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更快的提供文件下载的代码
2012/06/13 PHP
浅析HTTP消息头网页缓存控制以及header常用指令介绍
2013/06/28 PHP
PHP IE中下载附件问题解决方法
2014/01/07 PHP
header与缓冲区之间的深层次分析
2016/07/30 PHP
浅析php中array_map和array_walk的使用对比
2016/11/20 PHP
Laravel中七个非常有用但很少人知道的Carbon方法
2017/09/21 PHP
php curl简单采集图片生成base64编码(并附curl函数参数说明)
2019/02/15 PHP
新发现一个骗链接的方法(js读取cookies)
2012/01/11 Javascript
jQuery中:nth-child选择器用法实例
2014/12/31 Javascript
jquery.mobile 共同布局遇到的问题小结
2015/02/10 Javascript
JavaScript Date 知识浅析
2017/01/29 Javascript
微信小程序实现带刻度尺滑块功能
2017/03/29 Javascript
jQuery实现多张图片上传预览(不经过后端处理)
2017/04/29 jQuery
JS奇技之利用scroll来监听resize详解
2017/06/15 Javascript
vue-cli单页应用改成多页应用配置详解
2017/07/14 Javascript
es6学习之解构时应该注意的点
2017/08/29 Javascript
Angular 作用域scope的具体使用
2017/12/11 Javascript
js获取html页面代码中图片地址的实现代码
2018/03/05 Javascript
js正则相关知识点专题
2018/05/10 Javascript
JavaScript 反射和属性赋值实例解析
2019/10/28 Javascript
JavaScript实现多个物体同时运动
2020/03/12 Javascript
vuex的使用步骤
2021/01/06 Vue.js
[01:28:31]《加油DOTA》真人秀 第五期
2014/09/01 DOTA
[01:08:09]DOTA2上海特级锦标赛主赛事日 - 1 胜者组第一轮#1Liquid VS Alliance第二局
2016/03/02 DOTA
python结合API实现即时天气信息
2016/01/19 Python
Python 3中print函数的使用方法总结
2017/08/08 Python
使用python执行shell脚本 并动态传参 及subprocess的使用详解
2020/03/06 Python
CSS3 实现的火焰动画
2020/12/07 HTML / CSS
详解通过focusout事件解决IOS键盘收起时界面不归位的问题
2019/07/18 HTML / CSS
会计电算一体化个人简历的自我评价
2013/10/15 职场文书
司机检讨书
2014/02/13 职场文书
《庐山的云雾》教学反思
2014/04/22 职场文书
开展读书活动总结
2014/06/30 职场文书
2014年小学安全工作总结
2014/12/04 职场文书
2015年学生会主席工作总结
2015/04/21 职场文书
2015最新婚礼主持词
2015/06/30 职场文书