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截取函数(indexOf,join等)
Sep 01 Javascript
Jquery之Ajax运用 学习运用篇
Sep 26 Javascript
JS delegate与live浅析
Dec 21 Javascript
JavaScript定义类的几种方式总结
Jan 06 Javascript
IE中鼠标经过option触发mouseout的解决方法
Jan 29 Javascript
javascript手工制作悬浮菜单
Feb 12 Javascript
JavaScript学习笔记之创建对象
Mar 25 Javascript
jQuery实现的多张图无缝滚动效果【测试可用】
Sep 12 Javascript
正则表达式,替换所有HTML标签的简单实例
Nov 28 Javascript
微信小程序实现图片上传功能
May 28 Javascript
微信小程序常用简易小函数总结
Feb 01 Javascript
js 闭包深入理解与实例分析
Mar 19 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
简单实用的.net DataTable导出Execl
2013/10/28 PHP
php接口实现拖拽排序功能
2018/04/23 PHP
添加到收藏夹代码(兼容几乎所有的浏览器)
2007/01/09 Javascript
你需要知道的JavsScript可以做什么?
2007/06/29 Javascript
关于this和self的使用说明
2010/08/01 Javascript
使用javascipt---实现二分查找法
2013/04/10 Javascript
js中开关变量使用实例
2017/02/24 Javascript
Vue中保存用户登录状态实例代码
2017/06/07 Javascript
javascript将url解析为json格式的两种方法
2017/08/18 Javascript
vue 过滤器filter实例详解
2018/03/14 Javascript
vue 实现的树形菜的实例代码
2018/03/19 Javascript
微信小程序版本自动更新的方法
2019/06/14 Javascript
Vue项目中使用WebUploader实现文件上传的方法
2019/07/21 Javascript
js实现旋转的星空效果
2019/11/01 Javascript
微信小程序实现图片压缩
2019/12/03 Javascript
JS实现瀑布流效果
2020/03/07 Javascript
asyncio 的 coroutine对象 与 Future对象使用指南
2016/09/11 Python
Python数据分析之双色球中蓝红球分析统计示例
2018/02/03 Python
tensorflow 恢复指定层与不同层指定不同学习率的方法
2018/07/26 Python
详解PyCharm+QTDesigner+PyUIC使用教程
2019/06/13 Python
python3+PyQt5 数据库编程--增删改实例
2019/06/17 Python
django页面跳转问题及注意事项
2019/07/18 Python
详解Python 字符串相似性的几种度量方法
2019/08/29 Python
python数据库编程 ODBC方式实现通讯录
2020/03/27 Python
Python全局变量与global关键字常见错误解决方案
2020/10/05 Python
Python 实现PS滤镜的旋涡特效
2020/12/03 Python
2021年值得向Python开发者推荐的VS Code扩展插件
2021/01/25 Python
一个入门级python爬虫教程详解
2021/01/27 Python
戴尔美国官网:Dell
2016/08/31 全球购物
纽约市的奢华内衣目的地:Anya Lust
2019/08/02 全球购物
通信工程专业女生个人求职信
2013/09/21 职场文书
模范家庭事迹材料
2014/02/10 职场文书
我的梦想演讲稿
2014/04/30 职场文书
2016廉洁教育心得体会
2016/01/20 职场文书
fastdfs+nginx集群搭建的实现
2021/03/31 Servers
mysql中关键词exists的用法实例详解
2022/06/10 MySQL