12

I'm trying to write a function where I can specify any amount of array, and the return value will be an array containing the contents of all of the specified arrays.

I've done this, but it seems like a really slow and ugly way of doing it:

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));

Is there an inbuilt and more efficient / nice way of achieving this? The result does not need to be in the same order as the input - completely unsorted is fine.

Marty
  • 39,033
  • 19
  • 93
  • 162

3 Answers3

24

You can use concat.

If the parameters specify an array, the elements of that array are concatenated.

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);

To make a single array out of a 2 dimensional array you can use this function:

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);

You can also use varargs to merge multiple arrays:

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);
kapex
  • 28,903
  • 6
  • 107
  • 121
  • How do I do this with more than two arrays? – Marty Sep 26 '11 at 06:36
  • Is there a way I can do this with an object holding any given amount of arrays? Basically I want to loop through an array of arrays and merge the content of each array in the loop into one array. – Marty Sep 26 '11 at 06:59
  • `concat` creates a new array, and as we know `new` operation is expensive operation from the point of view of performance. Just use push (see my answer). – Narek Sep 06 '13 at 08:13
  • @Narek The special thing about `concat` is that, when given an array as argument it adds all elements to the new array. If you use push, you just create a two dimensional array. It's possible that push could be faster if used correctly (haven't seen any benchmarks though) but it's not interchangeable with concat in this function. – kapex Sep 06 '13 at 11:16
8

I don't know if this method is faster than using loops, but it is a (fancy) quick way to merge 2 arrays. (and it works in Javascript and 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
Mark Knol
  • 9,663
  • 3
  • 29
  • 44
  • 7
    You probably meant `arr1.push.apply(this, arr2);`. Using call gives you a different result (which will not be evident tracing the resulting array). If you call `push`, you'll end up with a jagged array, with 6 elements: '1, 2, 3, 4, 5' and another array containing the numbers `6, 7, 8, 9, 10` in the index 5. But you want a flat concatenated array, so either you use `concat` (which makes most sense in this case) or you use `push` and `apply`. – Juan Pablo Califano Sep 27 '11 at 12:07
  • 1
    I am a bit puzzled with "this" in apply. I think it's irrelevant due to its implementation, but in any case it would be more logical to be "arr1" – Bill Kotsias Jun 14 '15 at 14:19
2
function merge(...multi):Array
{
  var res:Array = [];

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

  return res;
}

Didnt try it, but something like this would help you.

ymutlu
  • 6,585
  • 4
  • 35
  • 47