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滑动杆实现购买日期选择效果
Sep 15 Javascript
JavaScript数组的一些奇葩行为
Jan 25 Javascript
jQuery.Uploadify插件实现带进度条的批量上传功能
Jun 08 Javascript
js实现定时进度条完成后切换图片
Jan 04 Javascript
EasyUI在Panel上动态添加LinkButton按钮
Aug 11 Javascript
Vue中使用vue-i18插件实现多语言切换功能
Apr 25 Javascript
微信小程序实现顶部导航特效
Jan 28 Javascript
JS基于对象的链表实现与使用方法示例
Jan 31 Javascript
JS学习笔记之贪吃蛇小游戏demo实例详解
May 29 Javascript
微信小程序iBeacon测距及稳定程序的实现解析
Jul 31 Javascript
解决layui页面按钮点击无反应,也不报错的问题
Sep 29 Javascript
详解Vue.js3.0 组件是如何渲染为DOM的
Nov 10 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 SEO优化之URL优化方法
2011/04/21 PHP
在smarty模板中使用PHP函数的方法
2011/04/23 PHP
php smarty truncate UTF8乱码问题解决办法
2014/06/13 PHP
php实现获取文章内容第一张图片的方法
2014/11/04 PHP
PHP多个图片压缩成ZIP的方法
2020/08/18 PHP
Laravel框架集成UEditor编辑器的方法图文与实例详解
2019/04/17 PHP
使用jQuery UI的tooltip函数修饰title属性的气泡悬浮框
2013/06/24 Javascript
jQuery 浮动导航菜单适合购物商品类型的网站
2014/09/09 Javascript
js实现简单的左右两边固定广告效果实例
2015/04/10 Javascript
JS和css实现检测移动设备方向的变化并判断横竖屏幕
2015/05/25 Javascript
微信和qq时间格式模板实例详解
2016/10/21 Javascript
移动适配的几种方案(三种方案)
2016/11/25 Javascript
javascript中闭包概念与用法深入理解
2016/12/15 Javascript
原生js验证简洁注册登录页面
2016/12/17 Javascript
vue中如何动态绑定图片,vue中通过data返回图片路径的方法
2018/02/07 Javascript
vue中Axios的封装与API接口的管理详解
2018/08/09 Javascript
js判断复选框是否选中的方法示例【基于jQuery】
2019/10/10 jQuery
[01:10]为家乡而战!完美世界城市挑战赛全国总决赛花絮
2019/07/25 DOTA
[56:42]VP vs RNG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
浅谈Python的垃圾回收机制
2016/12/17 Python
Python实现求数列和的方法示例
2018/01/12 Python
Django和Flask框架优缺点对比
2019/10/24 Python
Python实现弹球小游戏
2020/08/01 Python
python中strip(),lstrip(),rstrip()函数的使用讲解
2020/11/17 Python
我们是伦敦女孩:WalG
2018/01/08 全球购物
Airbnb爱彼迎官网:成为爱彼迎房东,赚取收入
2019/03/14 全球购物
ASOS西班牙官网:英国在线时尚和美容零售商
2020/01/10 全球购物
给校长的建议书200字
2014/05/16 职场文书
2014年项目工作总结
2014/11/24 职场文书
2014大学生学生会工作总结
2014/12/19 职场文书
2015年社区民政工作总结
2015/04/21 职场文书
幼儿园托班教育随笔
2015/08/14 职场文书
护理培训心得体会
2016/01/22 职场文书
会计专业2019暑假实习报告
2019/06/21 职场文书
XX部保密工作制度范本
2019/08/27 职场文书
Oracle数据库事务的开启与结束详解
2022/06/25 Oracle