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 学习之二 属性 文本与值(text,val)
Nov 25 Javascript
利用javascript实现web页面中指定区域打印
Oct 30 Javascript
jQuery.extend()、jQuery.fn.extend()扩展方法示例详解
May 08 Javascript
jQuery选择器源码解读(七):elementMatcher函数
Mar 31 Javascript
【JS+CSS3】实现带预览图幻灯片效果的示例代码
Mar 17 Javascript
深入理解关于javascript中apply()和call()方法的区别
Apr 12 Javascript
微信小程序自定义组件
Aug 16 Javascript
JS实现的贪吃蛇游戏案例详解
May 01 Javascript
JS操作字符串转数字的常见方法示例
Oct 29 Javascript
浅谈JavaScript中等号、双等号、 三等号的区别
Aug 06 Javascript
jQuery实现简单评论区功能
Oct 26 jQuery
解决pycharm双击但是无法打开的情况
Oct 31 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中用文本文件做数据库的实现方法
2008/03/27 PHP
php下使用以下代码连接并测试
2008/04/09 PHP
解析php中session的实现原理以及大网站应用应注意的问题
2013/06/17 PHP
laravel安装和配置教程
2014/10/29 PHP
php中Snoopy类用法实例
2015/06/19 PHP
Yii扩展组件编写方法实例分析
2015/06/29 PHP
php 反斜杠处理函数addslashes()和stripslashes()实例详解
2016/12/25 PHP
js修改table中Td的值(定义td的单击事件)
2013/01/10 Javascript
js同比例缩放图片的小例子
2013/10/30 Javascript
调用HttpHanlder的几种返回方式小结
2013/12/20 Javascript
javascript中的return和闭包函数浅析
2014/06/06 Javascript
Javascript MVC框架Backbone.js详解
2014/09/18 Javascript
JavaScript实现简单的二级导航菜单实例
2015/04/15 Javascript
Backbone.js框架中简单的View视图编写学习笔记
2016/02/14 Javascript
Angular 常用指令实例总结整理
2016/12/13 Javascript
jQuery模拟淘宝购物车功能
2017/02/27 Javascript
javaScript实现鼠标在文字上悬浮时弹出悬浮层效果
2020/04/12 Javascript
基于vue实现可搜索下拉框定制组件
2020/03/26 Javascript
详解Vue实战指南之依赖注入(provide/inject)
2018/11/13 Javascript
vue-router 控制路由权限的实现
2020/09/24 Javascript
利用Python读取txt文档的方法讲解
2018/06/23 Python
Python3实现腾讯云OCR识别
2018/11/27 Python
flask session组件的使用示例
2018/12/25 Python
python3.6.5基于kerberos认证的hive和hdfs连接调用方式
2020/06/06 Python
python 实现围棋游戏(纯tkinter gui)
2020/11/13 Python
详解canvas多边形(蜘蛛图)的画法示例
2018/01/29 HTML / CSS
伯利陶器:Burleigh Pottery
2018/01/03 全球购物
诺心蛋糕官网:LE CAKE
2018/08/25 全球购物
匈牙利超级网上商店和优惠:Alza.hu
2019/12/17 全球购物
个人简历自荐信
2013/12/05 职场文书
甲方资料员岗位职责
2013/12/13 职场文书
教师自我剖析材料(四风问题)
2014/09/30 职场文书
2014镇党委书记党建工作汇报材料
2014/11/02 职场文书
2014小学数学教研组工作总结
2014/12/06 职场文书
导游词之南京莫愁湖公园
2019/11/13 职场文书
Python爬虫基础讲解之请求
2021/05/13 Python