使用不同的方法结合/合并两个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实现目录浏览与编辑的代码
Oct 21 Javascript
Array.prototype.slice.apply的使用方法
Mar 17 Javascript
Javascript实现重力弹跳拖拽运动效果示例
Jun 28 Javascript
js中的this关键字详解
Sep 25 Javascript
node.js中的fs.mkdir方法使用说明
Dec 17 Javascript
使用jquery清空、复位整个输入域
Apr 02 Javascript
JS基于面向对象实现的选项卡效果示例
Dec 20 Javascript
React Native 自定义下拉刷新上拉加载的列表的示例
Mar 01 Javascript
VUE项目初建和常见问题总结
Sep 12 Javascript
Vue 自定义指令功能完整实例
Sep 17 Javascript
JS实现超级好看的鼠标小尾巴特效
Dec 01 Javascript
如何在Vue项目中添加接口监听遮罩
Jan 25 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
深入理解PHP之数组(遍历顺序)  Laruence原创
2012/06/13 PHP
php获取一个变量的名字的方法
2014/09/05 PHP
通过php修改xml文档内容的方法
2015/01/23 PHP
Yii2使用自带的UploadedFile实现的文件上传
2016/06/20 PHP
thinkPHP交易详情查询功能详解
2016/12/02 PHP
PHP新特性之字节码缓存和内置服务器
2017/08/11 PHP
解决laravel id非自增 模型取回为0 的问题
2019/10/11 PHP
用javascript实现无刷新更新数据的详细步骤 asp
2006/12/26 Javascript
[推荐]javascript 面向对象技术基础教程
2009/03/03 Javascript
jQuery AJAX 调用WebService实现代码
2010/03/24 Javascript
jquery select 设置默认选中的示例代码
2014/02/07 Javascript
百度判断手机终端并自动跳转js代码及使用实例
2014/06/11 Javascript
用js编写的简单的计算器代码程序
2015/08/04 Javascript
jquery配合.NET实现点击指定绑定数据并且能够一键下载
2016/10/28 Javascript
js CSS3实现卡牌旋转切换效果
2017/07/04 Javascript
jQuery实现table表格checkbox全选的方法分析
2018/07/04 jQuery
laydate如何根据开始时间或者结束时间限制范围
2018/11/15 Javascript
vue excel上传预览和table内容下载到excel文件中
2019/12/10 Javascript
TypeScript的安装、使用、自动编译的实现
2020/04/10 Javascript
Python 深入理解yield
2008/09/06 Python
Python编程中对文件和存储器的读写示例
2016/01/25 Python
python3读取csv和xlsx文件的实例
2018/06/22 Python
python读取txt文件,去掉空格计算每行长度的方法
2018/12/20 Python
python 利用turtle模块画出没有角的方格
2019/11/23 Python
pandas分组聚合详解
2020/04/10 Python
Python字节单位转换(将字节转换为K M G T)
2021/03/02 Python
CSS3中的@keyframes关键帧动画的选择器绑定
2016/06/13 HTML / CSS
UGG澳洲官网:UGG Australia
2018/04/26 全球购物
Snapfish爱尔兰:在线照片打印和个性化照片礼品
2018/09/17 全球购物
酒店实习个人鉴定
2013/12/07 职场文书
火车来了教学反思
2014/02/11 职场文书
应届生自荐信范文
2014/02/21 职场文书
船舶工程技术专业求职信
2014/08/07 职场文书
住宿生擅自离校检讨书
2014/09/22 职场文书
CSS完成视差滚动效果
2021/04/27 HTML / CSS
教你怎么用python实现字符串转日期
2021/05/24 Python