使用不同的方法结合/合并两个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 相关文章推荐
jQuery Div中加载其他页面的实现代码
Feb 27 Javascript
JavaScript 继承详解(四)
Jul 13 Javascript
Javascript面向对象编程
Mar 18 Javascript
js中事件的处理与浏览器对象示例介绍
Nov 29 Javascript
JQuery页面的表格数据的增加与分页的实现
Dec 10 Javascript
分享纯手写漂亮的表单验证
Nov 19 Javascript
JavaScript中的Reflect对象详解(ES6新特性)
Jul 22 Javascript
JavaScript使用ZeroClipboard操作剪切板
May 10 Javascript
VUE搭建手机商城心得和遇到的坑
Feb 21 Javascript
layuiAdmin循环遍历展示商品图片列表的方法
Sep 16 Javascript
antd中table展开行默认展示,且不需要前边的加号操作
Nov 02 Javascript
JavaScript实现缓动动画
Nov 25 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
《魔兽争霸3:重制版》翻车了?你想要的我们都没有
2019/11/07 魔兽争霸
PHP 地址栏信息的获取代码
2009/01/07 PHP
如何使用Linux的Crontab定时执行PHP脚本的方法
2011/12/19 PHP
phalcon model在插入或更新时会自动验证非空字段的解决办法
2016/12/29 PHP
Laravel解决nesting level错误和隐藏index.php的问题
2019/10/12 PHP
JavaScript中使用正则匹配多条,且获取每条中的分组数据
2010/11/30 Javascript
js中更短的 Array 类型转换
2011/10/30 Javascript
json字符串之间的相互转换示例代码
2014/08/21 Javascript
jquery文档操作wrap()方法实例简述
2015/01/10 Javascript
javascript内存分配原理实例分析
2017/04/10 Javascript
推荐三款不错的图片压缩上传插件(webuploader、localResizeIMG4、LUploader)
2017/04/21 Javascript
ReactNative页面跳转Navigator实现的示例代码
2017/08/02 Javascript
使用JS实现图片轮播的实例(前后首尾相接)
2017/09/21 Javascript
jQuery实现鼠标点击处心形漂浮的炫酷效果示例
2018/04/12 jQuery
jQuery中的for循环var与let的区别
2018/04/21 jQuery
jQuery实现每隔一段时间自动更换样式的方法分析
2018/05/03 jQuery
vue.js使用3DES加密的方法示例
2018/05/18 Javascript
elementUI Vue 单个按钮显示和隐藏的变换功能(两种方法)
2018/09/04 Javascript
javascript面向对象三大特征之封装实例详解
2019/07/24 Javascript
解决vue的router组件component在import时不能使用变量问题
2020/07/26 Javascript
在Python中marshal对象序列化的相关知识
2015/07/01 Python
PYQT5实现控制台显示功能的方法
2019/06/25 Python
Python Django 简单分页的实现代码解析
2019/08/21 Python
香港草莓网:Strawberrynet香港
2019/05/10 全球购物
美国最大和最受信任的二手轮胎商店:Bestusedtires.com
2020/06/02 全球购物
数据库设计的包括哪两种,请分别进行说明
2016/07/15 面试题
前台领班岗位职责
2013/12/04 职场文书
护理学应聘自荐书范文
2014/02/05 职场文书
团代会主持词
2014/04/02 职场文书
2015年公务员转正工作总结
2015/04/24 职场文书
2015年个人工作总结报告
2015/04/25 职场文书
2015年路政工作总结
2015/05/22 职场文书
2019大学生预备党员转正思想汇报
2019/06/21 职场文书
Python selenium的这三种等待方式一定要会!
2021/06/10 Python
如何使用pdb进行Python调试
2021/06/30 Python
Mysql关于数据库是否应该使用外键约束详解说明
2021/10/24 MySQL