## Adding to Arrays and Vectors

Adding on to existing arrays and vectors is one of those really common tasks that sounds dreary. Everyone knows about `push()` and `unshift()` for single elements and `concat()` for lots of elements. But what if you want to add a lot of elements to an existing array or vector without allocating a new array or vector? I have the solution.

If we combine `Function.apply()` and `Array.push()/Vector.push()`, the latter of which takes varargs, we can push a whole array of values:

var evens:Array = [2,4,6,8]; var odds:Array = [1,3,5,7]; // you can pass null instead of odds but you can't pass nothing (no crash though!) odds.push.apply(odds, evens); trace(odds); // 1,3,5,7,2,4,6,8 trace(odds.length); // 8

It even works with vectors:

var oddsVec:Vector.<int> = Vector.<int>([1,3,5,7]); oddsVec.push.apply(oddsVec, evens); trace(oddsVec); // 1,3,5,7,2,4,6,8 trace(oddsVec.length); // 8

Which leads to a semi-generalized function:

private function replaceVector(from:Array, into:Vector.<int>): void { into.length = 0; into.push.apply(into, from); }

Unfortunately, due to the lack of templating or generics support available to the AS3 programmer, this function cannot be truly generalized. You will have to write a version of this function for every single type of vector you would like to offer this replacing functionality. Each time, you will need to change the type of the vector. Also, `Function.apply()` will only accept an array of parameters, not a vector. This will not be caught at compile time, but will result in an error at runtime.

This is a good tip for avoiding allocation, which is slow, and later deallocation, which is also slow. The cost of the dynamic function call is totally worth it. I find that most of the time I do not need to use `concat()` due to this, as I am most often replacing the vector or array with the concatenated version of itself. I have a hunch that this is true for most people.

#1 by Promethe on October 8th, 2009 ·

Very interesting post! I’m using this technique in order to quickly build indices while walking through a BSP tree.

With your help, I know have only one push.apply per node instead of one push per face per node!

Amazing! :D

#2 by

rickyon May 5th, 2011 ·the trace output should be:

trace(odds); // 1,3,5,7,2,4,6,8

rather than

trace(odds); // 2,4,6,8,1,3,5,7

right?

#3 by jackson on May 5th, 2011 ·

Over 19 months and no one noticed the typo until you. Thanks for pointing it out. :)

#4 by Sidney de koning on July 30th, 2012 ·

Thank you, thank you, than you. This saved my ass while bugfixing.

I use this now to save incoming results from a webservice to a ‘cache’.

Very elegant sollution.

Thank you :)

Sidney

#5 by jackson on July 30th, 2012 ·

You’re welcome. :)