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向asp.net Mvc传递复杂json数据-ModelBinder篇
May 07 Javascript
js获取IFRAME当前的URL的方法
Nov 13 Javascript
ExtJS自定义主题(theme)样式详解
Nov 18 Javascript
浅析JavaScript中的类型和对象
Nov 29 Javascript
node.js中的fs.openSync方法使用说明
Dec 17 Javascript
javascript实现带下拉子菜单的导航菜单效果
May 14 Javascript
Spring mvc 接收json对象
Dec 10 Javascript
canvas仿iwatch时钟效果
Mar 06 Javascript
js canvas实现擦除效果示例代码
Apr 26 Javascript
详解Layer弹出层样式
Aug 21 Javascript
最新Javascript程序员面试试题和解题方法
Nov 23 Javascript
Vue项目中使用WebUploader实现文件上传的方法
Jul 21 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&amp;mysql(一)
2006/10/09 PHP
php的dl函数用法实例
2014/11/06 PHP
PHP利用百度ai实现文本和图片审核
2019/05/08 PHP
在textarea中屏蔽js的某个function的javascript代码
2007/04/20 Javascript
jquery 按钮状态效果 正常、移上、按下
2013/08/12 Javascript
JS实现可直接显示网页代码运行效果的HTML代码预览功能实例
2015/08/06 Javascript
编写高性能Javascript代码的N条建议
2015/10/12 Javascript
JS+CSS3实现超炫的散列画廊特效
2016/07/16 Javascript
AngularJS入门之动画
2016/07/27 Javascript
BootstrapValidator实现注册校验和登录错误提示效果
2017/03/10 Javascript
Vue通过URL传参如何控制全局console.log的开关详解
2017/12/07 Javascript
Vue.js实现数据响应的方法
2018/08/13 Javascript
小程序开发中如何使用async-await并封装公共异步请求的方法
2019/01/20 Javascript
学习node.js 断言的使用详解
2019/03/18 Javascript
vue项目在webpack2实现移动端字体自适配功能
2020/06/02 Javascript
如何使用JavaScript实现无缝滚动自动播放轮播图效果
2020/08/20 Javascript
JavaScript canvas实现跟随鼠标移动小球
2021/02/09 Javascript
[37:50]VP vs TNC Supermajor小组赛B组 BO3 第一场 6.2
2018/06/03 DOTA
Python中SOAP项目的介绍及其在web开发中的应用
2015/04/14 Python
Go语言基于Socket编写服务器端与客户端通信的实例
2016/02/19 Python
python中的闭包函数
2018/02/09 Python
10 行Python 代码实现 AI 目标检测技术【推荐】
2019/06/14 Python
在Python中实现函数重载的示例代码
2019/12/12 Python
python文件操作seek()偏移量,读取指正到指定位置操作
2020/07/05 Python
纯CSS实现颜色渐变效果(包含环形渐变、线性渐变、彩虹效果等)
2014/05/07 HTML / CSS
一款纯css3实现的圆形旋转分享按钮旋转角度可自己调整
2014/09/02 HTML / CSS
H5 meta小结(前端必看篇)
2016/08/24 HTML / CSS
华丽的手绘陶瓷:MacKenzie-Childs
2017/02/04 全球购物
欧洲顶级的童装奢侈品购物网站:Bambini Fashion(面向全球)
2018/04/24 全球购物
体育教学随笔感言
2014/02/24 职场文书
博士生求职信
2014/07/06 职场文书
幼儿园教师师德师风演讲稿:我自豪我是一名幼师
2014/09/10 职场文书
幼儿园国庆节活动总结
2015/03/23 职场文书
2015年上半年计生工作总结
2015/03/30 职场文书
解除租赁合同协议书
2016/03/21 职场文书
Java面试题冲刺第十六天--消息队列
2021/08/07 面试题