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 相关文章推荐
js如何实现设计模式中的模板方法
Jul 23 Javascript
JS获取地址栏参数的小例子
Aug 23 Javascript
使用JavaScript实现Java的List功能(实例讲解)
Nov 07 Javascript
jQuery实现的跨容器无缝拖动效果代码
Jun 21 Javascript
jQuery和hwSlider实现内容响应式可触控滑动切换效果附源码下载(二)
Jun 22 Javascript
详解如何用webpack打包一个网站应用项目
Jul 12 Javascript
javascript按钮禁用和启用的效果实例代码
Oct 29 Javascript
iview日期控件,双向绑定日期格式的方法
Mar 15 Javascript
JS正则表达式验证端口范围(0-65535)
Jan 06 Javascript
微信小程序实现上传照片代码实例解析
Aug 04 Javascript
不依任何赖第三方,单纯用vue实现Tree 树形控件的案例
Sep 21 Javascript
原生js+canvas实现验证码
Nov 29 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
jQuery中与toggleClass等价的程序段 以及未来学习的方向
2010/03/18 Javascript
flexigrid 类似ext grid的JS表格代码
2010/07/17 Javascript
文档对象模型DOM通俗讲解
2013/11/01 Javascript
jquery序列化form表单使用ajax提交后处理返回的json数据
2014/03/03 Javascript
js实现模拟计算器退格键删除文字效果的方法
2015/05/07 Javascript
asp.net中oracle 存储过程(图文)
2015/08/12 Javascript
jQuery1.9+中删除了live以后的替代方法
2016/06/17 Javascript
JS实现将数字金额转换为大写人民币汉字的方法
2016/08/02 Javascript
jQuery鼠标事件总结
2016/10/13 Javascript
jQuery设置Easyui校验规则(推荐)
2016/11/21 Javascript
canvas雪花效果核心代码分享
2017/02/19 Javascript
Vue组件的使用教程详解
2018/01/05 Javascript
vue2.0使用swiper组件实现轮播的示例代码
2018/03/03 Javascript
JavaScript常见鼠标事件与用法分析
2019/01/03 Javascript
Vue开发之封装分页组件与使用示例
2019/04/25 Javascript
layUI实现前端分页和后端分页
2019/07/27 Javascript
简述ES6新增关键字let与var的区别
2019/08/23 Javascript
Vue数据双向绑定底层实现原理
2019/11/22 Javascript
node.js基于dgram数据报模块创建UDP服务器和客户端操作示例
2020/02/12 Javascript
详解vuejs中执行npm run dev出现页面cannot GET/问题
2020/04/26 Javascript
vue实现动态表格提交参数动态生成控件的操作
2020/11/09 Javascript
[04:11]DOTA2亚洲邀请赛小组赛第一日 TOP10精彩集锦
2015/01/30 DOTA
使用Python构建Hopfield网络的教程
2015/04/14 Python
深入理解Django-Signals信号量
2019/02/19 Python
解决Python计算矩阵乘向量,矩阵乘实数的一些小错误
2019/08/26 Python
python 实现矩阵填充0的例子
2019/11/29 Python
python实现吃苹果小游戏
2020/03/21 Python
Python OpenCV读取中文路径图像的方法
2020/07/02 Python
爱尔兰领先的在线体育用品零售商:theGAAstore
2018/04/16 全球购物
要账委托书范本
2014/09/15 职场文书
四风自我剖析材料思想汇报
2014/10/01 职场文书
大学生操行评语大全
2014/12/31 职场文书
员工离职感谢信
2015/01/22 职场文书
2016八一建军节慰问信
2015/11/30 职场文书
浅谈Python列表嵌套字典转化的问题
2021/04/07 Python
PyTorch中的torch.cat简单介绍
2022/03/17 Python