使用不同的方法结合/合并两个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 相关文章推荐
JavaScript使用prototype定义对象类型
Feb 07 Javascript
JavaScript获取并更改input标签name属性的方法
Jul 02 Javascript
每天一篇javascript学习小结(RegExp对象)
Nov 17 Javascript
javascript实现保留两位小数的多种方法
Dec 18 Javascript
使用jQuery监听DOM元素大小变化
Feb 24 Javascript
分享JS数组求和与求最大值的方法
Aug 11 Javascript
JavaScript鼠标特效大全
Sep 13 Javascript
JavaScript中捕获/阻止捕获、冒泡/阻止冒泡方法
Dec 07 Javascript
JavaScript实现经典排序算法之选择排序
Dec 28 Javascript
jQuery加载及解析XML文件的方法实例分析
Jan 22 Javascript
jQuery Pagination分页插件使用方法详解
Feb 28 Javascript
对angularJs中controller控制器scope父子集作用域的实例讲解
Oct 08 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
海贼王:最美的悬赏令!
2020/03/02 日漫
wamp安装后自定义配置的方法
2014/08/23 PHP
PHP书写格式详解(必看)
2016/05/23 PHP
PHP数据库操作二:memcache用法分析
2017/08/16 PHP
javascript语句中的CDATA标签的意义
2007/05/09 Javascript
用XMLDOM和ADODB.Stream实现base64编码解码实现代码
2010/11/28 Javascript
javascript返回顶部效果(自写代码)
2013/01/06 Javascript
如何调试异步加载页面里包含的js文件
2014/10/30 Javascript
使用jQueryMobile实现滑动翻页效果的方法
2015/02/04 Javascript
JavaScript 数组some()和filter()的用法及区别
2016/05/20 Javascript
JS实现获取图片大小和预览的方法完整实例【兼容IE和其它浏览器】
2017/04/24 Javascript
jQuery ajax动态生成table功能示例
2017/06/14 jQuery
关于Google发布的JavaScript代码规范你要知道哪些
2018/04/04 Javascript
vue路由守卫+登录态管理实例分析
2019/05/21 Javascript
JS使用H5实现图片预览功能
2019/09/30 Javascript
jquery实现烟花效果(面向对象)
2020/03/10 jQuery
JavaScript实现动态生成表格
2020/08/02 Javascript
用js实现放大镜效果
2020/10/28 Javascript
vue3+typeScript穿梭框的实现示例
2020/12/29 Vue.js
[01:34]完美“圣”典宣传片震撼发布,12.17与你不见不散
2016/12/16 DOTA
教你如何在Django 1.6中正确使用 Signal
2014/06/22 Python
浅谈Python单向链表的实现
2015/12/24 Python
Python编程实现生成特定范围内不重复多个随机数的2种方法
2017/04/14 Python
对Python进行数据分析_关于Package的安装问题
2017/05/22 Python
详解【python】str与json类型转换
2019/04/29 Python
在python下使用tensorflow判断是否存在文件夹的实例
2019/06/10 Python
html5指南-6.如何创建离线web应用程序实现离线访问
2013/01/07 HTML / CSS
印度最大的旅游网站:MakeMyTrip
2016/10/05 全球购物
美国正宗设计师眼镜在线零售商:EYEZZ
2019/03/23 全球购物
家电业务员岗位职责
2014/03/10 职场文书
2014年关工委工作总结
2014/11/17 职场文书
辞职信格式模板
2015/02/27 职场文书
面试复试通知单
2015/04/24 职场文书
2016年校园社会综合治理宣传月活动总结
2016/03/16 职场文书
Java 超详细讲解hashCode方法
2022/04/07 Java/Android
微信告警的zabbix监控系统 监控整个NGINX集群
2022/04/18 Servers