使用不同的方法结合/合并两个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 Sort 表格排序
Oct 31 Javascript
js对象之JS入门之Array对象操作小结
Jan 09 Javascript
JS简单的轮播的图片滚动实例
Jun 17 Javascript
简单的代码实现jquery定时器
Nov 17 Javascript
js键盘上下左右键怎么触发function(实例讲解)
Dec 14 Javascript
JavaScript常用验证函数实例汇总
Nov 25 Javascript
轻松搞定js表单验证
Oct 13 Javascript
jquery ajaxfileupload异步上传插件使用详解
Feb 08 Javascript
zTree 树插件实现全国五级地区点击后加载的示例
Feb 05 Javascript
vue element动态渲染、移除表单并添加验证的实现
Jan 16 Javascript
用vscode开发vue应用的方法步骤
May 06 Javascript
微信小程序实现pdf、word等格式文件上传的方法
Sep 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获得当前的脚本网址
2007/12/10 PHP
php 仿Comsenz安装效果代码打包提供下载
2010/05/09 PHP
PHP文章采集URL补全函数(FormatUrl)
2012/08/02 PHP
php中使用session防止用户非法登录后台的方法
2015/01/27 PHP
[原创]PHP字符串中插入子字符串方法总结
2016/05/06 PHP
PHP手机号中间四位用星号*代替显示的实例
2017/06/02 PHP
PHP使用Redis长连接的方法详解
2018/02/12 PHP
Laravel模型事件的实现原理详解
2018/03/14 PHP
laravel 修改.htaccess文件 重定向public的解决方法
2019/10/12 PHP
PHP如何使用array_unshift()在数组开头插入元素
2020/09/01 PHP
js QQ客服悬浮效果实现代码
2014/12/12 Javascript
JQuery控制div外点击隐藏而div内点击不会隐藏的方法
2015/01/13 Javascript
jquery实现简单的轮换出现效果实例
2015/07/23 Javascript
js-FCC算法-No repeats please字符串的全排列(详解)
2017/05/02 Javascript
详解vue2.0+vue-video-player实现hls播放全过程
2018/03/02 Javascript
webpack4之如何编写loader的方法步骤
2019/06/06 Javascript
node获取客户端ip功能简单示例
2019/08/24 Javascript
Angular 多级路由实现登录页面跳转(小白教程)
2019/11/19 Javascript
viewer.js一个强大的基于jQuery的图像查看插件(支持旋转、缩放)
2020/04/01 jQuery
Vue中 axios delete请求参数操作
2020/08/25 Javascript
JS获取一个字符串中指定字符串第n次出现的位置
2021/02/10 Javascript
[02:38]2018DOTA2亚洲邀请赛赛前采访-VGJ.T
2018/04/03 DOTA
利用python操作SQLite数据库及文件操作详解
2017/09/22 Python
解决Python selenium get页面很慢时的问题
2019/01/30 Python
pygame实现贪吃蛇游戏(下)
2019/10/29 Python
浅析python表达式4+0.5值的数据类型
2020/02/26 Python
Keras—embedding嵌入层的用法详解
2020/06/10 Python
CSS教程:CSS3圆角属性
2009/04/02 HTML / CSS
世界上最大的隐形眼镜商店:1-800 Contacts
2018/11/03 全球购物
玩具公司的创业计划书
2013/12/31 职场文书
幼儿园春游活动方案
2014/01/19 职场文书
学前教育见习总结
2015/06/23 职场文书
教务处教学工作总结
2015/08/10 职场文书
加薪申请书应该这样写!
2019/07/04 职场文书
【海涛dota解说】DCG联赛第一周 LGD VS DH
2022/04/01 DOTA
Java中API的使用方法详情
2022/04/06 Java/Android