使用不同的方法结合/合并两个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事件列表解说
Dec 22 Javascript
FireFox中textNode分片的问题
Apr 10 Javascript
用于节点操作的API,颠覆原生操作HTML DOM节点的API
Dec 11 Javascript
javascript 3d 逐侦产品展示(核心精简)
Mar 26 Javascript
用js读、写、删除Cookie代码续篇
Dec 03 Javascript
jQuery将所有被选中的checkbox某个属性值连接成字符串的方法
Jan 24 Javascript
JQuery ztree带筛选、异步加载实例讲解
Feb 25 Javascript
在web中js实现类似excel的表格控件
Sep 01 Javascript
通过js修改input、select默认字体颜色
Apr 19 Javascript
使用ionic播放轮询广告的实现方法(必看)
Apr 24 Javascript
Javascript网页抢红包外挂实现分享
Jan 11 Javascript
jQuery实现获取多选框的值示例
Feb 07 jQuery
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/12/25 PHP
PHP实现仿Google分页效果的分页函数
2015/07/29 PHP
php生成唯一数字id的方法汇总
2015/11/18 PHP
Laravel 默认邮箱登录改成用户名登录的实现方法
2019/08/12 PHP
Laravel validate error处理,ajax,json示例
2019/10/25 PHP
提高代码性能技巧谈—以创建千行表格为例
2006/07/01 Javascript
Firefox 无法获取cssRules 的解决办法
2006/10/11 Javascript
js控制的回到页面顶端goTop的代码实现
2013/03/20 Javascript
jQuery .tmpl() 用法示例介绍
2014/08/21 Javascript
使用CDN和AJAX加速WordPress中jQuery的加载
2015/12/05 Javascript
jQuery选择器用法实例详解
2015/12/17 Javascript
angularjs 源码解析之scope
2016/08/22 Javascript
jQuery实现鼠标选中文字后弹出提示窗口效果【附demo源码】
2016/09/05 Javascript
vue上传图片组件编写代码
2017/07/26 Javascript
ES6学习教程之对象字面量详解
2017/10/09 Javascript
详解VUE2.X过滤器的使用方法
2018/01/11 Javascript
详谈vue+webpack解决css引用图片打包后找不到资源文件的问题
2018/03/06 Javascript
JS module的导出和导入的实现代码
2019/02/25 Javascript
js常用方法、检查是否有特殊字符串、倒序截取字符串操作完整示例
2020/01/26 Javascript
Vue.js使用axios动态获取response里的data数据操作
2020/09/08 Javascript
带你使用webpack快速构建web项目的方法
2020/11/12 Javascript
[02:12]Dota 2 推出全新英雄—— 电炎绝手
2019/08/23 DOTA
详解Python中 sys.argv[]的用法简明解释
2017/12/20 Python
Python中pip更新和三方插件安装说明
2018/07/08 Python
Python实现的字典排序操作示例【按键名key与键值value排序】
2018/12/21 Python
Python用Try语句捕获异常的实例方法
2019/06/26 Python
Pytorch的mean和std调查实例
2020/01/02 Python
Python如何实现在字符串里嵌入双引号或者单引号
2020/03/02 Python
css3背景图片透明叠加属性cross-fade简介及用法实例
2013/01/08 HTML / CSS
英国家电购物网站:Sonic Direct
2019/03/26 全球购物
中专三年学习的个人自我评价
2013/12/12 职场文书
副护士长竞聘演讲稿
2014/04/30 职场文书
亚运会口号
2014/06/20 职场文书
创新社会管理心得体会
2014/09/12 职场文书
Springboot使用Spring Data JPA实现数据库操作
2021/06/30 Java/Android
世界十大动漫制作公司排行榜,迪士尼上榜,第二是美国代表性文化符
2022/03/18 欧美动漫