使用不同的方法结合/合并两个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 相关文章推荐
JS JavaScript获取Url参数,src属性参数
Mar 09 Javascript
javascript 判断数组是否已包含了某个元素的函数
May 30 Javascript
简略的前端架构心得&amp;&amp;基于editor为例子的编码小技巧
Nov 25 Javascript
24款非常有用的 jQuery 插件分享
Apr 06 Javascript
学习javascript的闭包,原型,和匿名函数之旅
Oct 18 Javascript
jQuery时间日期三级联动(推荐)
Nov 27 Javascript
微信小程序 下拉列表的实现实例代码
Mar 08 Javascript
JS与jQuery实现子窗口获取父窗口元素值的方法
Apr 17 jQuery
vue拦截器Vue.http.interceptors.push使用详解
Apr 22 Javascript
javaScript实现鼠标在文字上悬浮时弹出悬浮层效果
Apr 12 Javascript
weui上传多图片,压缩,base64编码的示例代码
Jun 22 Javascript
javascript读取本地文件和目录方法详解
Aug 06 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 Mysql编程之高级技巧
2008/08/27 PHP
Linux系统下php获得系统分区信息的方法
2015/03/30 PHP
关于WordPress的SEO优化相关的一些PHP页面脚本技巧
2015/12/10 PHP
初识ThinkPHP控制器
2016/04/07 PHP
PHP开发之用微信远程遥控服务器
2018/01/25 PHP
JavaScript 全角转半角部分
2009/10/28 Javascript
jquery 仿QQ校友的DIV模拟窗口效果源码
2010/03/24 Javascript
cnblogs中在闪存中屏蔽某人的实现代码
2010/11/14 Javascript
JavaScript 类型的包装对象(Typed Wrappers)
2011/10/27 Javascript
鼠标滚轮改变图片大小的示例代码
2013/11/20 Javascript
JavaScript使表单中的内容显示在屏幕上的方法
2015/06/29 Javascript
javascript中Number的方法小结
2016/11/21 Javascript
jQuery实现遮罩层登录对话框
2016/12/29 Javascript
深入理解Vue router的部分高级用法
2018/08/15 Javascript
对angularJs中2种自定义服务的实例讲解
2018/09/30 Javascript
详解JavaScript对数组操作(添加/删除/截取/排序/倒序)
2019/04/28 Javascript
微信小程序template模板与component组件的区别和使用详解
2019/05/22 Javascript
PHP读取远程txt文档到数组并实现遍历
2020/08/25 Javascript
[16:04]DOTA2海涛带你玩炸弹 9月5日更新内容详解
2014/09/05 DOTA
[07:37]DOTA2-DPC中国联赛2月2日Recap集锦
2021/03/11 DOTA
Python爬虫实现爬取百度百科词条功能实例
2019/04/05 Python
Python流程控制 while循环实现解析
2019/09/02 Python
python之列表推导式的用法
2019/11/29 Python
Python实现图片批量加入水印代码实例
2019/11/30 Python
一款利用html5和css3动画排列人物头像的实例演示
2014/12/05 HTML / CSS
Lenox官网:精美的瓷器&独特的礼品
2017/02/12 全球购物
新加坡最早生产电动滑板车的制造商之一:FunsToTheFore
2020/09/08 全球购物
说出你对remoting 和webservice的理解和应用
2014/06/08 面试题
婚假请假条格式及范文
2014/04/10 职场文书
校园绿化美化方案
2014/06/08 职场文书
村当支部个人对照检查材料思想汇报
2014/10/06 职场文书
先进党员事迹材料
2014/12/24 职场文书
婚姻出轨保证书
2015/05/08 职场文书
2016年优秀党员教师先进事迹材料
2016/02/29 职场文书
关于MySQL中的 like操作符详情
2021/11/17 MySQL
mybatis-plus模糊查询指定字段
2022/04/28 Java/Android