js数组concat(数组合并成)

编者按:js数组的合并是前端生产中的常见需求。concat()方法是最常用的方法。在这里,作者给出了多种方法,包括将一个数组元素推或解转移到另一个数组;使用ES5的reduce()和reduceRight()方法;或推. apply(a,b)和unshift.apply(a,b)等。最后,作者推荐了ES5的reduce()和reduceRight()方法(注意它们与ie10以下的浏览器不兼容)。可以在移动终端、高级浏览器、微信小程序中使用。

这篇文章是JavaScript的一个基本技巧。我们将学习组合/合并两个JS数组的各种常见方法,并比较它们的优缺点。

先来看看:的具体场景。

var q=[ 5,5,1,9,9,6,4,5,8];

B=[‘tie ‘,’宜人车’,’ csdn ‘,’ ren ‘,’ fu ‘,’ Fei ‘];显然,数组Q和B简单拼接的结果是:

[

5, 5, 1, 9, 9, 6, 4, 5, 8,

铁’,车’,’ csdn ‘,’人’,’夫’,’非’

]concat(.)方法

最常见的用法如下:

var c=q . concat(b);q;//[5,5,1,9,9,6,4,5,8]

b;//[‘tie ‘,’宜人车’,’ csdn ‘,’ ren ‘,’ fu ‘,’ Fei ‘];c .//[5,5,1,9,9,6,4,5,8,’ tie ‘,’ plently car ‘,’ csdn ‘,’ ren ‘,’ fu ‘,’ fei’]可以看到,C是一个全新的数组,代表Q和B两个数组的组合,但是如果Q数组有10000个元素,那么B数组也有10000个元素吗?那么数组C现在有20000个元素,占用了两倍的内存。“那没问题!”你可能会想。只要把Q和B留空,那么就会被垃圾回收,对吗?问题解决了!

q=b=null//`q ‘和` b ‘现在可以被垃圾回收了吗?如果阵列都很小,那么自然没有问题。但是对于大型阵列,或者需要多次重复处理时,内存是有限的,需要优化。

循环插入

好,让我们尝试使用Array#push()方法:将一个数组的内容添加到另一个数组中。

//在“q”中插入数组“b”。

for(var I=0;i b .长度;I){ 0

q . push(b[I]);

} q;//[5,5,1,9,9,6,4,5,8,’ tie ‘,’张宗为车’,’ csdn ‘,’ ren ‘,’ fu ‘,’ Fei ‘]b=null;现在,两个原始数组(q b)的内容存储在q中,看来内存优化做得不错。但是Q阵小B阵大怎么办?为了内存和速度,我想在b前面插入一个更小的Q,没问题,就用unshift()方法代替push(),对应的循环遍历由大到小3360。

//`q ‘变成` b` :

for(var I=q . length-1;I=0;I-){ 0

b . unshift(q[I]);

} b;//[5,5,1,9,9,6,4,5,8,’ tie ‘,’宜人车’,’ csdn ‘,’ ren ‘,’ fu ‘,’ Fei ‘]q=null;实用技能

可悲的是,for循环是陈词滥调,很难维护。我们能做得更好吗?让我们先试试数组#减少:

//`b ‘到` q` :上

q=b.reduce(函数(coll,item){ 0

coll.push(项目);

返回coll

},q);q;//[5,5,1,9,9,6,4,5,8,’领带’,’车’,’任’,’付’,’费’]//或’ q ‘进’ 3360

b=q.reduceRight(函数(coll,item){ 0

coll.unshift(项目);

返回coll

},b);b;//[5,5,1,9,9,6,4,5,8,’ tie ‘,’宜人车’,’ csdn ‘,’ ren ‘,’ fu ‘,’ Fei’] array # reduce()和Array#reduceRight()都很高,但是

> 箭头函数(arrow-functions) 能让代码量大大减少, 但需要对每个数组元素执行函数调用, 也是很渣的手段. 那么下面的代码怎么样呢?

// `b` onto `q`:
q.push.apply( q, b );q; // [5,5,1,9,9,6,4,5,8,”tie”,”怡然的汽车”,”csdn”,”ren”,”fu”,”fei”]// or `q` into `b`:
b.unshift.apply( b, q );b; // [5,5,1,9,9,6,4,5,8,”tie”,”怡然的汽车”,”csdn”,”ren”,”fu”,”fei”]

BIG更高了,是吧!? 特别是 unshift() 方法不需要像前面那样考虑相反的顺序. ES6 的展开运算符(spread operator, 加 … 前缀)就更高端了: a.push( …b ) 或者 b.unshift( …a ) 但是,事实上这种方法还是太乐观了. 在这两种情况下,不管是将 a 或 b 传递给 apply() 作为第二个参数(apply方式调用Function时第一个参数在内部变成this,即context,上下文,作用域), 还是使用 … 展开运算符的方式, 实际上数组都会被打散成为函数的 arguments . 第一个主要的问题是,占用了双倍的内存(当然,是临时的!),因为需要将数组复制到函数栈之中. 此外,不同的JS引擎有不同的实现算法,可能会限制了函数可以传递的参数数量. 如果数组添加了一百万个元素, 那一定会超过函数栈所允许的大小, 不管是push() 或 unshift()调用. 这种方式只在几千个元素时可用,所以必须限制其不能超过一定范围.

注意: 你也可以试试 splice(), 肯定会发现他和 push(..)/unshift(..) 都是一样的限制.

一种选择是继续使用这种方法,但是采用分批次处理:

function combineInto(q,b) {
var len = q.length;
for (var i=0; i < len; i=i+5000) {
// 一次处理5000条
b.unshift.apply( b, q.slice( i, i+5000 ) );
}
}

等等,我们损害了代码的可读性(甚至是性能!). 在我们放弃之前结束这个旅程吧.

总结

Array#concat() 是久经考验的方法, 用于组合两个(或多个)数组. 但他创建了一个新的数组,而不是修改现有的一个. 有很多变通的手法,但他们都有不同的优缺点,需要根据实际情况来选择. 上面列出了各种 优点/缺点,也许最好的(包括没有列出的)方法是 reduce(..) 和 reduceRight(..) 无论你选择什么,都应该批判性地思考你的数组合并策略,而不是把它当作理所当然的事情.

译文:http://blog.csdn.net/renfufei/article/details/39376311

英文:Combining JS Arrays

喜欢这篇文章的朋友,欢迎关注、收藏、分享、评论,帮我上热门,你的支持,是我每日更新的动力!

喜欢前端的朋友可以点击关注一下我,每日分享精彩的前端文章!

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注