使用不同的方法结合/合并两个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 相关文章推荐
jquery $.ajax入门应用一
Nov 19 Javascript
jQuery autocomplate 自扩展插件、自动完成示例代码
Mar 28 Javascript
JQueryEasyUI datagrid框架的基本使用
Apr 08 Javascript
JS中eval函数的使用示例
Jul 21 Javascript
Javascript中innerHTML用法实例分析
Jan 12 Javascript
浅谈JS中json数据的处理
Jun 30 Javascript
jQuery实现的多张图无缝滚动效果【测试可用】
Sep 12 Javascript
详解从新建vue项目到引入组件Element的方法
Aug 29 Javascript
JS事件绑定的常用方式实例总结
Mar 02 Javascript
怎么理解wx.navigateTo的events参数使用详情
May 18 Javascript
js实现tab栏切换效果
Aug 02 Javascript
利用uni-app生成微信小程序的踩坑记录
Apr 05 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如何得到当前页和上一页的地址?
2006/11/27 PHP
PHP实现Javascript中的escape及unescape函数代码分享
2015/02/10 PHP
php将远程图片保存到本地服务器的实现代码
2015/08/03 PHP
php实现文章置顶功能的方法
2016/10/20 PHP
thinkPHP+ajax实现统计页面pv浏览量的方法
2017/03/15 PHP
才发现的超链接js导致网页中GIF动画停止的解决方法
2007/11/02 Javascript
jquery图片放大镜功能的实例代码
2013/03/26 Javascript
纯JS实现根据CSS的class选择DOM
2014/03/22 Javascript
jQuery+ajax实现动态执行脚本的方法
2015/01/27 Javascript
JS+CSS实现感应鼠标渐变显示DIV层的方法
2015/02/20 Javascript
javascript轮播图算法
2016/10/21 Javascript
Bootstrap table的使用方法
2016/11/02 Javascript
bootstrap datetimepicker 日期插件在火狐下出现一条报错信息的原因分析及解决办法
2017/03/08 Javascript
随机生成10个不重复的0-100的数字(实例讲解)
2017/08/16 Javascript
vue中使用vue-pdf的方法详解
2020/09/05 Javascript
复制粘贴功能的Python程序
2008/04/04 Python
python编写暴力破解FTP密码小工具
2014/11/19 Python
Python模块结构与布局操作方法实例分析
2017/07/24 Python
一些Centos Python 生产环境的部署命令(推荐)
2018/05/07 Python
对pandas中Series的map函数详解
2018/07/25 Python
Python3实现对列表按元组指定列进行排序的方法分析
2018/12/22 Python
python 杀死自身进程的实现方法
2019/07/01 Python
Python中*args和**kwargs的区别详解
2019/09/17 Python
python标准库os库的函数介绍
2020/02/12 Python
Python基础类继承重写实现原理解析
2020/04/03 Python
JAVA及PYTHON质数计算代码对比解析
2020/06/10 Python
基于HTML5 Canvas 实现弹出框效果
2017/06/05 HTML / CSS
基于HTML5代码实现折叠菜单附源码下载
2015/11/27 HTML / CSS
美国瑜伽品牌:Gaiam
2017/10/31 全球购物
设计师珠宝:Ylang 23
2018/05/11 全球购物
马来西亚与新加坡长途巴士售票网站:BusOnlineTicket.com
2018/11/05 全球购物
西班牙香水和化妆品连锁店:Druni
2019/05/05 全球购物
Groupon西班牙官方网站:在线优惠券和交易,节省高达70%
2021/03/13 全球购物
涉外离婚协议书怎么写
2014/11/20 职场文书
2014年宣传思想工作总结
2014/12/10 职场文书
分析设计模式之模板方法Java实现
2021/06/23 Java/Android