这是一篇简单的文章,关于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数组的N种方法的更多相关文章

  1. JavaScript数组的22种方法

    原文:http://www.cnblogs.com/xiaohuochai/p/5682621.html javascript中数组的22种方法   前面的话 数组总共有22种方法,本文将其分为对象继 ...

  2. 遍历Javascript数组的一种方法!

    应用场景: 如果您的数组只用一次的话就适用这种方法,因为遍历完后数组便清空了.代码如下: var arr=[1,5,6,2,3]; for(;i=arr.shift();){ console.log( ...

  3. JavaScript数组去重(5种方法)

    // 数组去重 let arr = ['a', 'b', 'b', 1, 1, 'true', true, true, NaN, NaN, 'NaN', undefined, undefined, n ...

  4. JavaScript数组打平(4种方法)

    let arr = [1, 2, [3, 4, 5, [6, 7, 8], 9], 10, [11, 12]]; flatten1 = arr => arr.flat(Infinity) fla ...

  5. python将两个数组合并成一个数组的两种方法的代码

    内容过程中,把写内容过程中常用的内容收藏起来,下面的资料是关于python将两个数组合并成一个数组的两种方法的内容,希望能对小伙伴们有帮助. c1 = ["Red","G ...

  6. javascript数组常用的遍历方法

    本篇文章给大家带来的内容是关于javascript数组常用的遍历方法(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 前言 本文主要介绍数组常见遍历方法:forEach.m ...

  7. 在WebBrowser中执行javascript脚本的几种方法整理(execScript/InvokeScript/NavigateScript) 附完整源码

    [实例简介] 涵盖了几种常用的 webBrowser执行javascript的方法,详见示例截图以及代码 [实例截图] [核心代码] execScript方式: 1 2 3 4 5 6 7 8 9 1 ...

  8. JQuery遍历json数组的3种方法

    这篇文章主要介绍了JQuery遍历json数组的3种方法,本文分别给出了使用each.for遍历json的方法,其中for又分成两种形式,需要的朋友可以参考下 一.使用each遍历 $(functio ...

  9. 合并BIN文件的两种方法(转)

    源:http://blog.chinaunix.net/uid-20745340-id-1878803.html 合并BIN文件的两种方法 在单片机的开发过程中,经常需要将两个单独的BIN文件合并成一 ...

随机推荐

  1. React Native踩坑之The SDK directory 'xxxxx' does not exist

    相信和我一样,自己摸索配置环境的过程中,第一次配,很可能就遇到了这个比较简单地错误,没有配置sdk环境 解决办法 在电脑,系统环境变量中,添加一个sdk的环境变量 uploading-image-95 ...

  2. 【原创】获取MySQL crash 时的core file

    最近有台服务器的MySQL经常crash,为了进一步定位问题,开启了mysql core file功能,开启步骤如下,供参考 [开启步骤] 1. my.cnf文件中增加2个配置选项 [mysqld] ...

  3. 1020 Tree Traversals (25)(25 point(s))

    problem Suppose that all the keys in a binary tree are distinct positive integers. Given the postord ...

  4. [ 原创 ] Java基础1--Java中super和this的用法和区别

    许多同学在学习Java时分不清楚this和super的用法和区别,今天偶然发现一片加精的博文,看完内容准备自己也写下来积累一下 1.如果想在子类的构造方法中调用父类的构造方法,必须在子类的构造方法中使 ...

  5. 内容播放colorbox

    1.需要的js (1)jquery (2)colorbox (http://www.jacklmoore.com/colorbox/ 下载文件夹,其中有js.css文件) //加载的时候注意文件的路径 ...

  6. ZOJ2112 BZOJ1901 Dynamic Rankings 树套树 带修改的区间第k小

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2112 树套树,线段树套splay或者主席树套树状数组,我抄了一下hzwer ...

  7. ARC 101 D - Median of Medians

    题面在这里! 这种题只能二分答案把qwwq,直接做根本做不了啊... 首先你需要知道如何通过 一个区间<=x的数有多少个 来判断x和这个区间中位数的关系. 很显然当数有至少 [L/2]+1 个( ...

  8. CSS实现背景透明,文字不透明

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  9. Nodejs线上日志部署

    Nodejs 被越来越多的使用到线上系统中,但线上系统没有日志怎么行呢. 一.forever记录日志 我的线上系统使用forever来启动服务,最开始就直接使用了forever来记录 forever ...

  10. Git_git的诞生

    很多人都知道,Linus在1991年创建了开源的Linux,从此,Linux系统不断发展,已经成为最大的服务器系统软件了. Linus虽然创建了Linux,但Linux的壮大是靠全世界热心的志愿者参与 ...