使用不同的方法结合/合并两个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 相关文章推荐
Firefox window.close()的使用注意事项
Apr 11 Javascript
Wordpress ThickBox 添加“查看原图”效果代码
Dec 11 Javascript
JS操作select下拉框动态变动(创建/删除/获取)
Jun 02 Javascript
Jquery 例外被抛出且未被接住原因介绍
Sep 04 Javascript
javascript字符串与数组转换汇总
May 26 Javascript
js实现网站最上边可关闭的浮动广告条代码
Sep 04 Javascript
JavaScript直播评论发弹幕切图功能点集合效果代码
Jun 26 Javascript
jQuery EasyUI开发技巧总结
Sep 26 jQuery
详解vue组件中使用路由方法
Feb 12 Javascript
JavaScript制作3D旋转相册
Aug 02 Javascript
十分钟教你上手ES2020新特性
Feb 12 Javascript
如何手写简易的 Vue Router
Oct 10 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+JS无限级可伸缩菜单详解(简单易懂)
2007/01/02 PHP
php实现把数组按指定的个数分隔
2014/02/17 PHP
PHP判断是手机端还是PC端 PHP判断是否是微信浏览器
2017/03/15 PHP
laravel 5.4中实现无限级分类的方法示例
2017/07/27 PHP
Mac系统下搭建Nginx+php-fpm实例讲解
2020/12/15 PHP
取得父标签
2006/11/14 Javascript
Javascript匿名函数的一种应用 代码封装
2010/06/27 Javascript
40个有创意的jQuery图片、内容滑动及弹出插件收藏集之一
2011/12/31 Javascript
8个实用的jQuery技巧
2014/03/04 Javascript
React创建组件的三种方式及其区别
2017/01/12 Javascript
Node.js常用工具之util模块
2017/03/09 Javascript
js实现自定义进度条效果
2017/03/15 Javascript
JavaScript数据结构之二叉树的查找算法示例
2017/04/13 Javascript
浅谈JS 数字和字符串之间相互转化的纠纷
2017/10/20 Javascript
JavaScript实现为事件句柄绑定监听函数的方法分析
2017/11/14 Javascript
微信小程序页面调用自定义组件内的事件详解
2019/09/12 Javascript
JS+CSS实现过渡特效
2021/01/02 Javascript
[02:57]2014DOTA2国际邀请赛 选手辛苦解说更辛苦
2014/07/10 DOTA
python中的一些类型转换函数小结
2013/02/10 Python
利用Python循环(包括while&amp;for)各种打印九九乘法表的实例
2017/11/06 Python
bluepy 一款python封装的BLE利器简单介绍
2019/06/25 Python
Python打开文件、文件读写操作、with方式、文件常用函数实例分析
2020/01/07 Python
卸载tensorflow-cpu重装tensorflow-gpu操作
2020/06/23 Python
Pytorch模型迁移和迁移学习,导入部分模型参数的操作
2021/03/03 Python
使用Html5实现异步上传文件,支持跨域,带有上传进度条
2016/09/17 HTML / CSS
HTML5实现直播间评论滚动效果的代码
2020/05/27 HTML / CSS
一站式跨境收款解决方案:Payoneer(派安盈)
2018/09/06 全球购物
请用Java实现列出某个目录下的所有文件
2013/09/23 面试题
医学生自我鉴定范文
2013/11/08 职场文书
大学生新学期计划书
2014/04/28 职场文书
村庄绿化方案
2014/05/07 职场文书
2014年村官工作总结
2014/11/24 职场文书
学生病假条怎么写
2015/08/17 职场文书
《世界多美呀》教学反思
2016/02/22 职场文书
感恩信:写给爸爸妈妈的一封感谢信
2019/09/12 职场文书
一劳永逸彻底解决pip install慢的办法
2021/05/24 Python