使用不同的方法结合/合并两个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 相关文章推荐
简明json介绍
Sep 28 Javascript
jquery动态加载js/css文件方法(自写小函数)
Oct 11 Javascript
node.js中的console.info方法使用说明
Dec 09 Javascript
js实现select跳转菜单新窗口效果代码分享(超简单)
Aug 21 Javascript
js中不同的height, top的区别对比
Sep 24 Javascript
jQuery动态加载css文件实现方法
Jun 15 Javascript
vue不通过路由直接获取url中参数的方法示例
Aug 24 Javascript
BootStrap模态框和select2合用时input无法获取焦点的解决方法
Sep 01 Javascript
浅谈在koa2中实现页面渲染的全局数据
Oct 09 Javascript
捕获未处理的Promise错误方法
Oct 13 Javascript
vue全局自定义指令-元素拖拽的实现代码
Apr 14 Javascript
Vue的双向数据绑定实现原理解析
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操作XML作为数据库的类
2010/12/19 PHP
PHP内核探索:变量概述
2014/01/30 PHP
php数组中包含中文的排序方法
2014/06/03 PHP
php防止站外远程提交表单的方法
2014/10/20 PHP
浅谈php自定义错误日志
2015/02/13 PHP
php文件扩展名判断及获取文件扩展名的N种方法
2015/09/12 PHP
php基于dom实现的图书xml格式数据示例
2017/02/03 PHP
源码分析 Laravel 重复执行同一个队列任务的原因
2017/12/25 PHP
JavaScript TO HTML 转换
2006/06/26 Javascript
jQuery实战之仿淘宝商城左侧导航效果
2011/04/12 Javascript
AeroWindow 基于JQuery的弹出窗口插件
2011/06/27 Javascript
Jquery刷新页面背景图片随机变换的实现方法
2013/03/15 Javascript
js简易namespace管理器 实例代码
2013/06/21 Javascript
上传图片js判断图片尺寸和格式兼容IE
2014/09/01 Javascript
关于Javascript回调函数的一个妙用
2016/08/29 Javascript
php 修改密码实现代码
2017/05/24 Javascript
详解vue-cil和webpack中本地静态图片的路径问题解决方案
2017/09/27 Javascript
JavaScript定义及输出螺旋矩阵的方法详解
2017/12/01 Javascript
Vue实现表格批量审核功能实例代码
2019/05/28 Javascript
vue elementUI使用tabs与导航栏联动
2019/06/21 Javascript
深入讲解Python编程中的字符串
2015/10/14 Python
详解python上传文件和字符到PHP服务器
2017/11/24 Python
Python实现Pig Latin小游戏实例代码
2018/02/02 Python
python selenium登录豆瓣网过程解析
2019/08/10 Python
通过python 执行 nohup 不生效的解决
2020/04/16 Python
在Django中自定义filter并在template中的使用详解
2020/05/19 Python
Python基于network模块制作电影人物关系图
2020/06/19 Python
天美时手表加拿大官网:Timex加拿大
2016/09/01 全球购物
Bailey帽子官方商店:Bailey Hats
2018/09/25 全球购物
资产运营委托书范本
2014/10/16 职场文书
《青山不老》教学反思
2016/02/22 职场文书
使用Python的开发框架Brownie部署以太坊智能合约
2021/05/28 Python
图解排序算法之希尔排序Java实现
2021/06/26 Java/Android
opencv检测动态物体的实现
2021/07/21 Python
关于PostgreSQL JSONB的匹配和交集问题
2021/09/14 PostgreSQL
教你使用Python获取QQ音乐某个歌手的歌单
2022/04/03 Python