JavaScript数组合并的多种方法


Posted in Javascript onMay 22, 2016

这是一篇简单的文章,关于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 相关文章推荐
JQuery 插件制作实践 xMarquee插件V1.0
Apr 02 Javascript
javascript Array数组对象的扩展函数代码
May 22 Javascript
jquery实现div拖拽宽度示例代码
Jul 31 Javascript
Mac地址验证的javascript代码
Nov 09 Javascript
Boostrap模态窗口的学习小结
Mar 28 Javascript
bootstrap和jQuery.Gantt的css冲突 如何解决
May 29 Javascript
Node.js利用Net模块实现多人命令行聊天室的方法
Dec 23 Javascript
JQuery获取鼠标进入和离开容器的方向
Dec 29 Javascript
vue2.0使用Sortable.js实现的拖拽功能示例
Feb 21 Javascript
JavaScript定时器setTimeout()和setInterval()详解
Aug 18 Javascript
JS脚本加载后执行相应回调函数的操作方法
Feb 28 Javascript
vue插件开发之使用pdf.js实现手机端在线预览pdf文档的方法
Jul 12 Javascript
浅析JavaScript回调函数应用
May 22 #Javascript
为什么JavaScript没有块级作用域
May 22 #Javascript
全面解析Bootstrap中nav、collapse的使用方法
May 22 #Javascript
全面解析bootstrap格子布局
May 22 #Javascript
Bootstrap模块dropdown实现下拉框响应
May 22 #Javascript
基于Bootstrap实现图片轮播效果
May 22 #Javascript
基于Vue.js的表格分页组件
May 22 #Javascript
You might like
php中ob(Output Buffer 输出缓冲)函数使用方法
2007/07/21 PHP
php使用file函数、fseek函数读取大文件效率对比分析
2016/11/04 PHP
Zend Framework前端控制器用法示例
2016/12/11 PHP
解决extjs在firefox中关闭窗口再打开后iframe中js函数访问不到的问题
2008/11/06 Javascript
Js 去掉字符串中的空格(实现代码)
2013/11/19 Javascript
js防阻塞加载的实现方法
2016/09/09 Javascript
AngularJS bootstrap启动详解及实例代码
2016/09/14 Javascript
Bootstrap进度条学习使用
2017/02/09 Javascript
JS实现鼠标拖拽盒子移动及右键点击盒子消失效果示例
2019/01/29 Javascript
node中IO以及定时器优先级详解
2019/05/10 Javascript
使用Angular material主题定义自己的组件库的配色体系
2019/09/04 Javascript
Vue基于localStorage存储信息代码实例
2020/11/16 Javascript
python带参数打包exe及调用方式
2019/12/21 Python
Django Xadmin多对多字段过滤实例
2020/04/07 Python
django自带的权限管理Permission用法说明
2020/05/13 Python
keras处理欠拟合和过拟合的实例讲解
2020/05/25 Python
python爬虫请求头设置代码
2020/07/28 Python
python3定位并识别图片验证码实现自动登录功能
2021/01/29 Python
python如何修改文件时间属性
2021/02/05 Python
Ancheer官方户外和运动商店:销售电动自行车
2019/08/07 全球购物
美国最大的户外装备和服装购物网站:Backcountry
2019/10/15 全球购物
世界经理人咨询有限公司面试
2014/09/23 面试题
大学生标准推荐信范文
2013/11/25 职场文书
总经理秘书的岗位职责
2013/12/27 职场文书
金融管理专业毕业生求职信
2014/03/12 职场文书
幼儿园小班评语
2014/04/18 职场文书
12.4全国法制宣传日活动总结
2014/11/01 职场文书
财务负责人岗位职责
2015/02/03 职场文书
董事长助理岗位职责
2015/02/11 职场文书
支行行长岗位职责
2015/02/15 职场文书
争先创优个人总结
2015/03/04 职场文书
储备店长岗位职责
2015/04/14 职场文书
培训感想范文
2015/08/07 职场文书
MySQL慢查询的坑
2021/04/28 MySQL
利用Pycharm连接服务器的全过程记录
2021/07/01 Python
我去timi了,一起去timi是什么意思?
2022/04/13 杂记