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的反射问题
Apr 07 Javascript
html向js方法传递参数具体实现
Aug 08 Javascript
yepnope.js使用详解及示例分享
Jun 23 Javascript
微信小程序 欢迎界面开发的实例详解
Nov 30 Javascript
JS实现的样式切换功能tableCSS实例
Dec 30 Javascript
AngularJS Controller作用域
Jan 09 Javascript
JS实现选定指定HTML元素对象中指定文本内容功能示例
Feb 13 Javascript
vue利用better-scroll实现轮播图与页面滚动详解
Oct 20 Javascript
详解Vue.js中引入图片路径的几种方式
Jun 17 Javascript
express框架下使用session的方法
Jul 31 Javascript
vue中keep-alive,include的缓存问题
Nov 26 Javascript
jQuery实现简单评论功能
Aug 19 jQuery
浅析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删除文件夹的三种方法
2013/06/09 PHP
javascript学习笔记(四)function函数部分
2014/09/30 Javascript
jQuery对象的selector属性用法实例
2014/12/27 Javascript
js如何准确获取当前页面url网址信息
2020/09/13 Javascript
JQuery点击行tr实现checkBox选中的简单实例
2016/05/26 Javascript
ajax的分页查询示例(不刷新页面)
2017/01/11 Javascript
template.js前端模板引擎使用详解
2017/10/10 Javascript
nuxt+axios解决前后端分离SSR的示例代码
2017/10/24 Javascript
JS/HTML5游戏常用算法之追踪算法实例详解
2018/12/12 Javascript
javascript实现的时间格式加8小时功能示例
2019/06/13 Javascript
ElementUI之Message功能拓展详解
2019/10/18 Javascript
浅谈关于vue中scss公用的解决方案
2019/12/02 Javascript
[00:39]DOTA2上海特级锦标赛 Liquid战队宣传片
2016/03/04 DOTA
Python HTTP客户端自定义Cookie实现实例
2017/04/28 Python
Python基于tkinter模块实现的改名小工具示例
2017/07/27 Python
详解Python 模拟实现生产者消费者模式的实例
2017/08/10 Python
Django实战之用户认证(初始配置)
2018/07/16 Python
Python3实现的简单工资管理系统示例
2019/03/12 Python
使用django的objects.filter()方法匹配多个关键字的方法
2019/07/18 Python
Pandas透视表(pivot_table)详解
2019/07/22 Python
Django 源码WSGI剖析过程详解
2019/08/05 Python
Python常用模块logging——日志输出功能(示例代码)
2019/11/20 Python
python numpy实现rolling滚动案例
2020/06/08 Python
python自动化测试三部曲之request+django实现接口测试
2020/10/07 Python
香港个人化生活购物网站:Ballyhoo Limited
2016/09/10 全球购物
美国卡车、吉普车和SUV零件网站:4 Wheel Parts
2016/11/24 全球购物
台湾网购生鲜第一品牌:i3Fresh爱上新鲜
2017/10/26 全球购物
String s = new String(“xyz”);创建了几个String Object?
2015/08/05 面试题
幼师自荐信
2013/10/26 职场文书
咖啡店的创业计划书,让你hold不住
2014/01/03 职场文书
个人投资计划书
2014/05/01 职场文书
国庆节标语大全
2014/10/08 职场文书
乡镇党的群众路线教育实践活动个人整改方案
2014/10/31 职场文书
2015年度个人业务工作总结
2015/04/27 职场文书
学习雷锋主题班会
2015/08/14 职场文书
发工资啦!教你用Python实现邮箱自动群发工资条
2021/05/10 Python