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 相关文章推荐
让iframe框架网页在任何浏览器下自动伸缩
Aug 18 Javascript
利用location.hash实现跨域iframe自适应
May 04 Javascript
js展开闭合效果演示代码
Jul 24 Javascript
JavaScript动态创建div等元素实例讲解
Jan 06 Javascript
详解JS中Array对象扩展与String对象扩展
Jan 07 Javascript
使用JS正则表达式 替换括号,尖括号等
Nov 29 Javascript
Node.js如何响应Ajax的POST请求并且保存为JSON文件详解
Mar 10 Javascript
JavaScript解决浮点数计算不准确问题的方法分析
Jul 09 Javascript
Vue组件之单向数据流的解决方法
Nov 10 Javascript
Vue源码学习之关于对Array的数据侦听实现
Apr 23 Javascript
vue响应式更新机制及不使用框架实现简单的数据双向绑定问题
Jun 27 Javascript
在vue中封装方法以及多处引用该方法详解
Aug 14 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文本数据库的搜索方法
2006/10/09 PHP
php模拟asp中的XmlHttpRequest实现http请求的代码
2011/03/24 PHP
PHP设计模式之观察者模式实例
2016/02/22 PHP
PHP获取文本框、密码域、按钮的值实例代码
2017/04/19 PHP
PHP PDOStatement::debugDumpParams讲解
2019/01/30 PHP
Yii 框架使用数据库(databases)的方法示例
2020/05/19 PHP
jQuery EasyUI中对表格进行编辑的实现代码
2010/06/10 Javascript
通过DOM脚本去设置样式信息
2010/09/19 Javascript
jQuery实现的购物车物品数量加减功能代码
2016/11/16 Javascript
Node.js Express 框架 POST方法详解
2017/01/23 Javascript
ajax分页效果(bootstrap模态框)
2017/01/23 Javascript
jQuery Migrate 插件用法实例详解
2019/05/22 jQuery
java实现单链表增删改查的实例代码详解
2019/08/30 Javascript
toString.call()通用的判断数据类型方法示例
2020/08/28 Javascript
[03:30]完美盛典趣味短片 CSGO2019年度名场面
2019/12/07 DOTA
使用python在校内发人人网状态(人人网看状态)
2014/02/19 Python
windows下python模拟鼠标点击和键盘输示例
2014/02/28 Python
Python列表生成器的循环技巧分享
2015/03/06 Python
python脚本爬取字体文件的实现方法
2017/04/29 Python
python列表的增删改查实例代码
2018/01/30 Python
在NumPy中创建空数组/矩阵的方法
2018/06/15 Python
django 自定义过滤器的实现
2019/02/26 Python
Python中单线程、多线程和多进程的效率对比实验实例
2019/05/14 Python
python seaborn heatmap可视化相关性矩阵实例
2020/06/03 Python
Django 构建模板form表单的两种方法
2020/06/14 Python
python实现xml转json文件的示例代码
2020/12/30 Python
东南亚地区最大的购物网站Lazada新加坡站点:Lazada.sg
2016/07/17 全球购物
ALDI奥乐齐官方海外旗舰店:德国百年超市
2017/12/27 全球购物
戴尔美国官方折扣店:Dell Outlet
2018/02/13 全球购物
美国隐形眼镜零售商:LensPure
2019/03/10 全球购物
餐饮服务员岗位职责
2015/02/09 职场文书
毕业生学校组织意见
2015/06/04 职场文书
领导干部学习十八届五中全会精神心得体会
2016/01/05 职场文书
Jupyter notebook 更改文件打开的默认路径操作
2021/05/21 Python
Mysql效率优化定位较低sql的两种方式
2021/05/26 MySQL
vue使用wavesurfer.js解决音频可视化播放问题
2022/04/04 Vue.js