使用不同的方法结合/合并两个JS数组


Posted in Javascript onSeptember 18, 2014

这是一篇简单的文章,关于JavaScript数组使用的一些技巧。我们将使用不同的方法结合/合并两个JS数组,以及讨论每个方法的优点/缺点。

让我们先考虑下面这情况:

var a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ];

var b = [ "foo", "bar", "baz", "bam", "bun", "fun" ];

很显然最简单的结合结果应该是:
[

1, 2, 3, 4, 5, 6, 7, 8, 9,

"foo", "bar", "baz", "bam" "bun", "fun"

]
concat(..)
这是最常见的做法:
var c = a.concat( b );

a; // [1,2,3,4,5,6,7,8,9]

b; // ["foo","bar","baz","bam","bun","fun"]

c; // [1,2,3,4,5,6,7,8,9,"foo","bar","baz","bam","bun","fun"]
正如你所看到的,C是一个全新的数组,表示a和b两个数组的组合,并让A和B不变。简单吧?

但如果a有10,000个元素,而b也有一万个元素? C就会有2万个元素,所以a和b的内内存使用就会翻倍。

“没问题!”,你说。让它们被垃圾回收,把A和B设置为null,问题解决了!

a = b = null; // 'a'和'b'就被回收了

呵呵。对于只有几个元素的小数组,这没啥问题。但对于大数组,或者在内存有限的系统中需要经常重复这个过程,它其实还有很多改进的地方。
循环插入

好吧,让我们将一个数组的内容复制到另一个,使用: Array#push(..)

// `b` onto `a`

for (var i=0; i < b.length; i++) {

a.push( b[i] );

}

a; // [1,2,3,4,5,6,7,8,9,"foo","bar","baz","bam","bun","fun"]

b = null;
现在,数组a有了数组b的内容。

似乎有更好的内存占用。

但如果a数组比较小?出于内存和速度的原因,你可能要把更小的a放到b的前面,。没问题,只需将push(..)换成unshift(..)即可:

// `a` into `b`:

for (var i=a.length-1; i >= 0; i--) {

b.unshift( a[i] );

}

b; // [1,2,3,4,5,6,7,8,9,"foo","bar","baz","bam","bun","fun"]

功能技巧

不过for循环确实比较丑,而且不好维护。我们可以做的更好吗?

这是我们的第一次尝试,使用Array#reduce:

// `b` onto `a`:

a = b.reduce( function(coll,item){

coll.push( item );

return coll;

}, a );
a; // [1,2,3,4,5,6,7,8,9,"foo","bar","baz","bam","bun","fun"]

// or `a` into `b`:

b = a.reduceRight( function(coll,item){

coll.unshift( item );

return coll;

}, b );

b; // [1,2,3,4,5,6,7,8,9,"foo","bar","baz","bam","bun","fun"]

Array#reduce(..) 和 Array#reduceRight(..)是不错的,但他们是一点点笨拙。 ES6=>的箭头函数将减少一些代码量,但它仍然需要一个函数,每个元素都需要调用一次,不是很完美。

那这个怎么样:

// `b` onto `a`:
a.push.apply( a, b );

a; // [1,2,3,4,5,6,7,8,9,"foo","bar","baz","bam","bun","fun"]

// or `a` into `b`:

b.unshift.apply( b, a );

b; // [1,2,3,4,5,6,7,8,9,"foo","bar","baz","bam","bun","fun"]

这是一个要好很多吧?特别是因为 unshift(..)方法在这里并不需要担心前面的反向排序。 ES6的spead操作会更漂亮: a.push( ...b ) 或 b.unshift( ...a

数组最大长度限制

第一个主要的问题是,内存使用量增长了一倍(当然只是暂时的!)被追加内容基本上是通过函数调用将元素复制到堆栈中。此外,不同的JS引擎都有拷贝数据长度的限制。

所以,如果数组有一百万个元素,你肯定会超出了push(...)或unshift(...)允许调用堆栈的限制。唉,处理几千个元素它会做得很好,但你必须要小心,不能超过合理的长度限值。

注意: 你可以尝试一下splice(...),它跟push(...)和unshift(...)一样都有这种问题。

有一种方法可以避免这种最大长度限制。

function combineInto(a,b) {

var len = a.length;

for (var i=0; i < len; i=i+5000) {

b.unshift.apply( b, a.slice( i, i+5000 ) );

}

}
等一下,我们的可读性倒退了。 就这样吧,可能会越改越差,呵。
Javascript 相关文章推荐
在模板页面的js使用办法
Apr 01 Javascript
js word表格动态添加代码
Jun 07 Javascript
js倒计时小程序
Nov 05 Javascript
JS保存和删除cookie操作 判断cookie是否存在
Nov 13 Javascript
js实现搜索框关键字智能匹配代码
Mar 26 Javascript
jQuery添加和删除输入文本框标签代码
May 20 Javascript
jQuery实现的网页换肤效果示例
Sep 20 Javascript
EasyUI中的dataGrid的行内编辑
Jun 22 Javascript
微信小程序 循环及嵌套循环的使用总结
Sep 26 Javascript
Angularjs 根据一个select的值去设置另一个select的值方法
Aug 13 Javascript
VUE单页面切换动画代码(全网最好的切换效果)
Oct 31 Javascript
vue框架中props的typescript用法详解
Feb 17 Javascript
js实现按Ctrl+Enter发送效果
Sep 18 #Javascript
javascript搜索框点击文字消失失焦时文本出现
Sep 18 #Javascript
输入框过滤非数字的js代码
Sep 18 #Javascript
小结Node.js中非阻塞IO和事件循环
Sep 18 #Javascript
JavaScript将取代AppleScript?
Sep 18 #Javascript
Javascript MVC框架Backbone.js详解
Sep 18 #Javascript
JS回调函数的应用简单实例
Sep 17 #Javascript
You might like
用PHP的超级变量$_POST获取HTML表单(HTML Form) 数据
2011/05/07 PHP
for循环连续求和、九九乘法表代码
2012/02/20 PHP
详解PHP内置访问资源的超时时间 time_out file_get_contents read_file
2013/06/03 PHP
PHP实现通用alert函数的方法
2015/03/11 PHP
PHP stream_context_create()函数的使用示例
2015/05/12 PHP
PHP缩略图生成和图片水印制作
2017/01/07 PHP
PHP中关于php.ini参数优化详解
2020/02/28 PHP
jquery实现的让超出显示范围外的导航自动固定屏幕最顶上
2011/09/22 Javascript
javascript模拟地球旋转效果代码实例
2013/12/02 Javascript
JavaScript运行时库属性一览表
2014/03/14 Javascript
jQuery实现自定义下拉列表
2015/01/05 Javascript
Node.js模块封装及使用方法
2016/03/06 Javascript
JS中动态创建元素的三种方法总结(推荐)
2016/10/20 Javascript
浅谈JS验证表单文本域输入空格的问题
2017/02/14 Javascript
JavaScript 中调用 Kotlin 方法实例详解
2017/06/09 Javascript
js 索引下标之li集合绑定点击事件
2018/01/12 Javascript
JS对象与json字符串相互转换实现方法示例
2018/06/14 Javascript
Vue 中 a标签上href无法跳转的解决方式
2019/11/12 Javascript
Python编程之string相关操作实例详解
2017/07/22 Python
python和pygame实现简单俄罗斯方块游戏
2021/02/19 Python
解决 jupyter notebook 回车换两行问题
2020/04/15 Python
python 字符串格式化的示例
2020/09/21 Python
手把手教你用Django执行原生SQL的方法
2021/02/18 Python
英国口碑最好的的维他命胶囊品牌:Myvitamins(有中文站)
2016/12/03 全球购物
特步官方商城:Xtep
2017/03/21 全球购物
什么是Linux虚拟文件系统VFS
2012/01/31 面试题
大学军训自我鉴定
2013/12/15 职场文书
音乐教学反思
2014/02/02 职场文书
村居抓节水倡议书
2014/05/19 职场文书
大学英语专业求职信
2014/06/21 职场文书
班子成员四风问题自我剖析材料
2014/09/29 职场文书
企业三严三实学习心得体会
2014/10/13 职场文书
女性健康讲座主持词
2015/07/04 职场文书
团队合作精神学习心得体会
2016/01/19 职场文书
2016年教育局“我们的节日——端午节”主题活动总结
2016/04/01 职场文书
Springboot中如何自动转JSON输出
2022/06/16 Java/Android