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下用gb2312编码解码实现方法
Dec 31 Javascript
提升你网站水平的jQuery插件集合推荐
Apr 19 Javascript
javascript ready和load事件的区别示例介绍
Aug 30 Javascript
浅析jQuery Ajax通用js封装
Jun 22 Javascript
js实现无缝循环滚动
Jun 23 Javascript
bootstrap table表格插件使用详解
May 08 Javascript
微信小程序实现之手势锁功能实例代码
Jul 19 Javascript
javascript的this关键字详解
May 20 Javascript
微信接入之获取用户头像的方法步骤
Sep 23 Javascript
uni-app如何实现增量更新功能
Jan 03 Javascript
解决vue组件没显示,没起作用,没报错,但该显示的组件没显示问题
Sep 02 Javascript
Vue自定义铃声提示音组件的实现
Jan 22 Vue.js
浅析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下将XML转换为数组
2010/01/01 PHP
PHP中使用sleep函数实现定时任务实例分享
2014/08/21 PHP
php代码检查代理ip的有效性
2016/08/19 PHP
PHP实现的常规正则验证helper公共类完整实例
2017/04/27 PHP
PhpStorm配置Xdebug调试的方法步骤
2019/02/02 PHP
javaScript parseInt字符转化为数字函数使用小结
2009/11/05 Javascript
漂亮的jquery提示效果(仿腾讯弹出层)
2013/02/05 Javascript
jquery弹出框的用法示例(一)
2013/08/26 Javascript
原生javascript图片自动或手动切换示例附演示源码
2013/09/04 Javascript
js数组的操作指南
2014/12/28 Javascript
详细分析JavaScript变量类型
2015/07/08 Javascript
基于JavaScript实现树形下拉框
2016/08/10 Javascript
JavaScript实现省市县三级级联特效
2017/05/16 Javascript
详解.vue文件中监听input输入事件(oninput)
2017/09/19 Javascript
Vue中的字符串模板的使用
2018/05/17 Javascript
对vue中methods互相调用的方法详解
2018/08/30 Javascript
jquery实现的分页显示功能示例
2019/08/23 jQuery
VUEX-action可以修改state吗
2019/11/19 Javascript
[26:24]完美副总裁、DOTA2负责人蔡玮专访:电竞如人生
2014/09/11 DOTA
[01:01:43]EG vs VP 2018国际邀请赛淘汰赛BO3 第二场 8.24
2018/08/25 DOTA
[00:23]魔方之谜解锁款式
2018/12/20 DOTA
Python中给List添加元素的4种方法分享
2014/11/28 Python
详解Python中用于计算指数的exp()方法
2015/05/14 Python
Django 反向生成url实例详解
2019/07/30 Python
python使用Geany编辑器配置方法
2020/02/21 Python
python修改linux中文件(文件夹)的权限属性操作
2020/03/05 Python
Python操作dict时避免出现KeyError的几种解决方法
2020/09/20 Python
css3实现信纸/同学录效果的示例代码
2018/12/11 HTML / CSS
毕业生护理专业个人求职信范文
2014/01/04 职场文书
幼儿园大班评语大全
2014/04/17 职场文书
小学教师师德师风自我剖析材料
2014/09/29 职场文书
驳回起诉裁定书
2015/05/19 职场文书
有关三国演义的读书笔记
2015/06/25 职场文书
运动会通讯稿100字
2015/07/20 职场文书
七年级作文(600字3篇)
2019/09/24 职场文书
JavaScript 防篡改对象的用法示例
2021/04/24 Javascript