AS3最快的合并多个数组的方法

12

我想编写一个函数,可以指定任意数量的数组,并且返回值将是包含所有指定数组内容的数组。

我已经做到了,但这似乎是一种非常缓慢且难看的方法:

var ar1:Array = [1,2,3,4,5,6,7,8,9];
var ar2:Array = ['a','b','c','d','e','f','g','h'];


function merge(...multi):Array
{
    var out:String = "";

    for each(var i:Array in multi)
    {
        out += i.join(',');
    }

    return out.split(',');
}

trace(merge(ar1, ar2));

有没有内建的更有效/更好的方法来实现这个?结果不需要与输入相同的顺序-完全无序是可以的。

3个回答

24

您可以使用concat方法。

如果参数是一个数组,则连接该数组的元素。

var ar1:Array = [1,2,3,4,5,6,7,8,9];
var ar2:Array = ['a','b','c','d','e','f','g','h'];
var ar3:Array = ['i','j','k','l'];

var ar4 = ar1.concat(ar2, ar3); // or: ar1.concat(ar2).concat(ar3);

想要将二维数组转换为单一的一维数组,你可以使用这个函数:

private function flatten(arrays:Array):Array {
    var result:Array = [];
    for(var i:int=0;i<arrays.length;i++){
        result = result.concat(arrays[i]);
    }
    return result;
}

// call
var ar4 = [ar1, ar2, ar3];
var ar5 = flatten(ar4);

你也可以使用varargs来合并多个数组:

private function merge(...arrays):Array {
    var result:Array = [];
    for(var i:int=0;i<arrays.length;i++){
        result = result.concat(arrays[i]);
    }
    return result;
}

// call
var ar5 = merge(ar1, ar2, ar3);

我如何使用超过两个数组来完成这个操作? - Marty
有没有一种方法可以使用包含任意数量的数组的对象来完成这个操作?基本上,我想循环遍历一个数组的数组,并将循环中每个数组的内容合并到一个数组中。 - Marty
concat 创建一个新的数组,而我们知道 new 操作从性能角度来看是昂贵的操作。只需使用 push(请参见我的答案)。 - Narek
@Narek concat 的特殊之处在于,当作为参数传入一个数组时,它会将所有元素添加到新数组中。如果使用 push,则只会创建一个二维数组。如果使用正确(尚未看到任何基准测试),则 push 可能更快,但在此函数中无法与 concat 互换。 - kapex

8

我不知道这种方法是否比使用循环更快,但它是一种(花哨的)快速合并2个数组的方法。(而且它适用于Javascript和Actionscript)

var arr1:Array = [1,2,3,4,5]
var arr2:Array = [6,7,8,9,10]

arr1.push.apply(this, arr2); // merge 
// arr1.push.call(this, arr2); // don't use this. see comment below

trace(arr1) // 1,2,3,4,5,6,7,8,9,10

7
你可能想表达的是 arr1.push.apply(this, arr2);。使用 call 方法会得到不同的结果(不易追踪导致的结果数组)。如果你调用 push 方法,会得到一个不规则的数组,其中包含6个元素:'1, 2, 3, 4, 5' 和另一个数组在索引5处包含数字 6, 7, 8, 9, 10。但你希望得到一个扁平的连接数组,所以你可以使用 concat 方法(这在这种情况下最合理),或者使用 pushapply 方法。 - Juan Pablo Califano
1
我对apply中的"this"有点困惑。我认为它由于其实现方式而不相关,但无论如何,更合理的是使用"arr1"。 - Bill Kotsias

2
function merge(...multi):Array
{
  var res:Array = [];

  for each(var i:Array in multi)
  {
    res = res.concat(i);
  }

  return res;
}

我没有尝试过这个方法,但是类似这样的内容会对您有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接