使用不同的方法结合/合并两个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 相关文章推荐
greybox——不开新窗口看新的网页
Feb 20 Javascript
JavaScript类和继承 constructor属性
Mar 04 Javascript
javascript 判断字符串是否包含某字符串及indexOf使用示例
Oct 18 Javascript
原生JS实现拖拽图片效果
Aug 27 Javascript
D3.js实现雷达图的方法详解
Sep 22 Javascript
微信小程序之仿微信漂流瓶实例
Dec 09 Javascript
详解Vue2.0里过滤器容易踩到的坑
Jun 01 Javascript
解析Vue 2.5的Diff算法
Nov 28 Javascript
jQuery设置下拉框显示与隐藏效果的方法分析
Sep 15 jQuery
通过实例了解JS执行上下文运行原理
Jun 17 Javascript
vue自定义组件(通过Vue.use()来使用)即install的用法说明
Aug 11 Javascript
VUE中的v-if与v-show区别介绍
Mar 13 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
Laravel使用scout集成elasticsearch做全文搜索的实现方法
2018/11/30 PHP
PHP7 新增功能
2021/03/09 PHP
JavaScript Event事件学习第一章 Event介绍
2010/02/07 Javascript
从零开始学习jQuery (二) 万能的选择器
2010/10/01 Javascript
jQuery 验证插件 Web前端设计模式(asp.net)
2010/10/17 Javascript
myFocus slide3D v1.1.0 使用方法与下载
2011/01/12 Javascript
javascript算法题 求任意一个1-9位不重复的N位数在该组合中的大小排列序号
2012/07/21 Javascript
将json当数据库一样操作的javascript lib
2013/10/28 Javascript
js判断客户端是iOS还是Android等移动终端的方法
2013/12/11 Javascript
jquery禁用右键单击功能屏蔽F5刷新
2014/03/17 Javascript
jQuery+css3动画属性制作猎豹浏览器宽屏banner焦点图
2015/03/16 Javascript
浅谈jQuery中setInterval()方法
2015/07/07 Javascript
JS获取鼠标相对位置的方法
2016/09/20 Javascript
基于ajax和jsonp的原生封装(实例)
2017/10/16 Javascript
webstorm添加*.vue文件支持
2018/05/08 Javascript
jQuery中$原理实例分析
2018/08/13 jQuery
Vue中多个元素、组件的过渡及列表过渡的方法示例
2019/02/13 Javascript
[41:52]2018DOTA2亚洲邀请赛3月29日 小组赛A组 TNC VS OpTic
2018/03/30 DOTA
python检测空间储存剩余大小和指定文件夹内存占用的实例
2018/06/11 Python
Python 从列表中取值和取索引的方法
2018/12/25 Python
python中多个装饰器的调用顺序详解
2019/07/16 Python
美国顶级防滑鞋:Shoes For Crews
2017/03/27 全球购物
Speedo澳大利亚官网:全球领先游泳品牌
2018/02/04 全球购物
雷蛇美国官网:Razer
2020/04/03 全球购物
Auguste The Label官网:澳大利亚一家精品女装时尚品牌
2020/06/14 全球购物
写自荐信的七个技巧
2013/10/15 职场文书
热爱祖国演讲稿
2014/05/04 职场文书
城管执法人员纪律作风整顿思想汇报
2014/09/13 职场文书
2014国庆黄金周超市促销活动方案
2014/09/21 职场文书
教师个人师德工作总结2015
2015/05/12 职场文书
致运动员的广播稿
2015/08/19 职场文书
2016公司新年问候语
2015/11/11 职场文书
解决golang在import自己的包报错的问题
2021/04/29 Golang
Go语言grpc和protobuf
2022/04/13 Golang
Win10/Win11 任务栏替换成经典样式
2022/04/19 数码科技
HTML CSS 一个标签实现带动画的抖音LOGO
2022/04/26 HTML / CSS