使用不同的方法结合/合并两个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 相关文章推荐
不能再简单的无闪刷新验证码原理很简单
Nov 05 Javascript
input按钮的事件处理大全
Dec 10 Javascript
原生js实现shift/ctrl/alt按键的获取
Apr 08 Javascript
JS日期和时间选择控件升级版(自写)
Aug 02 Javascript
JAVA四种基本排序方法实例总结
Jul 24 Javascript
在Linux系统中搭建Node.js开发环境的简单步骤讲解
Jan 26 Javascript
vue中的router-view组件的使用教程
Oct 23 Javascript
你不知道的Vue技巧之--开发一个可以通过方法调用的组件(推荐)
Apr 15 Javascript
原生javascript中this几种常见用法总结
Feb 24 Javascript
JavaScript实现打砖块游戏
Feb 25 Javascript
vue 清空input标签 中file的值操作
Jul 21 Javascript
使用vue编写h5公众号跳转小程序的实现代码
Nov 27 Vue.js
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代码技巧的小结
2013/06/02 PHP
Laravel框架模板加载,分配变量及简单路由功能示例
2018/06/11 PHP
csdn 博客中实现运行代码功能实现
2009/08/29 Javascript
js png图片(有含有透明)在IE6中为什么不透明了
2010/02/07 Javascript
javascript 隐藏/显示指定的区域附HTML元素【legend】用法
2010/03/05 Javascript
javascript中字符串拼接需注意的问题
2010/07/13 Javascript
javascript unicode与GBK2312(中文)编码转换方法
2013/11/14 Javascript
jQuery中的insertBefore(),insertAfter(),after(),before()区别介绍
2016/09/01 Javascript
浅谈jquery采用attr修改form表单enctype不起作用的问题
2016/11/25 Javascript
原生js实现可拖动的登录框效果
2017/01/21 Javascript
jQuery中绑定事件bind() on() live() one()的异同
2017/02/23 Javascript
微信小程序实现YDUI的ScrollNav组件
2018/02/02 Javascript
[01:24:09]Ti4 冒泡赛第二轮DK vs C9 1
2014/07/14 DOTA
Python中MySQLdb和torndb模块对MySQL的断连问题处理
2015/11/09 Python
Windows系统下使用flup搭建Nginx和Python环境的方法
2015/12/25 Python
python3+PyQt5实现支持多线程的页面索引器应用程序
2018/04/20 Python
pandas DataFrame创建方法的方式
2019/08/02 Python
python可视化篇之流式数据监控的实现
2019/08/07 Python
python 字符串常用函数详解
2019/09/11 Python
Django-xadmin后台导入json数据及后台显示信息图标和主题更改方式
2020/03/11 Python
Python如何生成xml文件
2020/06/04 Python
Python基于os.environ从windows获取环境变量
2020/06/09 Python
Python pathlib模块使用方法及实例解析
2020/10/05 Python
Python实现异步IO的示例
2020/11/05 Python
澳大利亚领先的在线葡萄酒零售商:Get Wines Direct
2018/03/27 全球购物
维德科技C#面试题笔试题
2015/12/09 面试题
留学自荐信写作方法
2014/01/27 职场文书
会计学专业学生的求职信范文
2014/01/27 职场文书
报关员个人职业生涯规划书
2014/03/12 职场文书
财政局长个人总结
2015/03/04 职场文书
运动会班级口号霸气押韵
2015/12/24 职场文书
关于考试抄袭的检讨书
2019/11/02 职场文书
浅谈@Value和@Bean的执行顺序问题
2021/06/16 Java/Android
idea下配置tomcat避坑详解
2022/04/12 Servers
Vue组件化(ref,props, mixin,.插件)详解
2022/05/15 Vue.js
pycharm无法安装cv2模块问题
2022/05/20 Python