OurJS


OurJS-我们的JS, 我们的技术-IT文摘; 专注JS相关领域;
我们热爱编程, 我们热爱技术;我们是高大上, 有品味的码农;

欢迎您订阅我们的技术周刊


我们会向您分享我们精心收集整理的,最新的行业资讯,技术动态,外文翻译,热点文章;
我们使用第三方邮件列表向您推送,我们不保存您的任何个人资料,注重您的隐私,您可以随时退订,

欢迎分享您的观点,经验,技巧,心得

让我们一起找寻程序员的快乐,探索技术, 发现IT人生的乐趣;


本网站使用缓存技术每次加载仅需很小流量, 可在手机中流畅浏览;
如果您发现任何BUG,请即时告知我们: ourjs(at)ourjs.com

合并JavaScript数组的N种方法


分享到
分类 JS学习   关键字 JavaScript   发布 ourjs  1410751065163
注意 转载须保留原文链接,译文链接,作者译者等信息。  
By Kyle Simpson on 2014年9月9号


这是一篇简单的文章,关于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 ) );
    }
}

等一下,我们的可读性倒退了。 就这样吧,可能会越改越差,呵。


原文地址: 点此
社区评论 ( Beta版 )
OnceDoc 您自己的企业内容管理系统——文档、流程、知识库、报表、网盘All In One

访问404页面,寻找丢失儿童
 热门文章 - 分享最多
  1. JavaScript构建(编绎)系统大比拼:Grunt vs. Gulp vs. NPM
  2. NodeBots-JavaScript在智能设备驱动(物联网)中的崛起
  3. CSS的力量:用一个DIV画图
  4. 内存管理技巧:如何避免JavaScript的内存泄露
  5. 微软Azure云推出基于JSON的NoSQL数据库DocumentDB
  6. 响应式设计在图片上的应用: 一个HTML元素如何让Web更快
  7. 前置逗号是不好的JavaScript代码书写习惯吗?
  8. CSS垂直水平完全居中手册
  9. Chrome V8将实现ES6的类语法(class)
  10. 今天我去面试, 受打击了:你是学 .net 的吧?
  11. AirJD-简单好用的免费建站工具

 相关阅读 - JS学习
  1. 内存管理技巧:如何避免JavaScript的内存泄露
  2. JavaScript中匿名函数和命名函数的性能差异
  3. JavaScript中怪异的地方
  4. 前置逗号是不好的JavaScript代码书写习惯吗?
  5. 在node.js响应流中设置多个Set-Cookie header属性
  6. JavaScript:世界上误解最深的语言
  7. 告别Node.js
  8. Node.js手册:require是如何工作的
  9. JavaScript最大堆栈的数量
  10. 7个步骤:让JavaScript变得更好

 关键字 - JavaScript
  1. 5个现在就该使用的数组Array方法: indexOf/filter/forEach/map/reduce详解
  2. 用HTML5原生实现拖放或排序
  3. 少年,不要滥用箭头函数啊:JS中lambda表达式的优缺点和使用场景
  4. 用原生HTML5控件实现输入框自动提示(下拉列表补全)功能
  5. OnceIO模块开发:模块注册、模块路由、静态文件重定向以及如何开发与设计一个功能扩展模块
  6. 抛弃jQuery,深入原生的JavaScript
  7. JavaScript中NaN的秘密
  8. 从一行CSS调试代码中学到的JavaScript知识
  9. 在Debian(Raspberry Pi)树莓派上安装NodeJS
  10. NodeBots-JavaScript在智能设备驱动(物联网)中的崛起

 欢迎订阅 - 技术周刊

我们热爱编程, 我们热爱技术; 我们是高端, 大气, 上档次, 有品味, 时刻需要和国际接轨的码农; 欢迎您订阅我们的技术周刊; 您只需要在右上角输入您的邮箱即可; 我们注重您的隐私,您可以随时退订.
加入我们吧! 让我们一起找寻码农的快乐,探索技术, 发现IT人生的乐趣;


 关注我们

我们的微信公众号: ourjs-com
打开微信扫一扫即可关注我们:
IT文摘-程序员(码农)技术周刊

ourjs官方微信号