I would have sworn that there was a built in Array function for appending the contents of one array to another array.... But when I went to look it up, I found I was wrong.
Array.concat() concatenates the contents of two arays, but it creates and returns a new array rather than appending to the array on which it is invoked.
Array.push() and Array.splice() modify the array on which they are called, but append the array itself, rather than appending the contents of the array.
There isn't even an append() function in the Array Extras package coming in Firefox 1.5.
Here, therefore, is my solution to this problem:
// Append the elements of the array a to this array
Array.prototype.append = function(a) {
Array.prototype.push.apply(this, a);
}




Unfortunately, after you add such a custom method to the array prototype, it will be enumerated in for/in loops - which pretty much renders for/in loops useless.
Also, calling it append is going to confuse the hell out of people. Call it extend.
Chris: do you use for/in on arrays? That's not an idiom I've ever found useful: I just do a regular for loop. I would certainly never extend Object.prototype, but I'd certainly consider doing it for Array.
Having said that, though, I put it in the prototype here just for the coolness factor of doing that. If I were going to be deploying it myself, I'd probably just make it a regular function.
Bob: append() seems clearer to me than extend() does. Does append have some other meaning in the python world? What do you expect a function named append to do?
appendElements() would make it clear that it appends the elements of the argument array rather than the array itself. I can see calling it that.
There is no precedent anywhere that says appendElements is a good thing to call it. extend is what it's called in Python, addAll is what it's called in Java's ArrayList, AddRange is what it's called in .NET's ArrayList, etc. PHP and Ruby have no equivalent, and Perl would just use push with a list argument that gets exploded.
MochiKit.Base calls it extend, but its implementation is a bit more flexible.
Oh, in Python, append is the equivalent to push in JavaScript. Exactly one element is appended to the end of the list. Python does not call it push.
The thing that bothers me about .concat (and I hope I'm remembering this correctly), is that it FLATTENS the arguments. Sometimes I really want an array of arrays.
Adam,
concat() flattens its arguments, but not recursively. So if you want to concatenate arrays b and c to array a, do this:
a.concat([a,b])
instead of this:
a.concat(a,b)
Bob,
As a Java guy, I should have thought to use addAll() instead of append() or appendElements(). I like that name better.
I don't like extend() as a name. I'm not used to it. And, I notice that it is used in libraries like prototype.js (if I remember correctly) and maybe also MochiKit for extending objects. I think that the semantics of extending objects by adding properties are sufficiently different from the semantics of appending elements to an array that using the same name is a bad idea...
Your opinion probably differs, of course :-)
Why not just:
Array.prototype.append = Array.prototype.push;
I always find myself using push() anyways.
Prototype uses Object.prototype.extend(other) to do an "Object.extend" in Ruby terms.
MochiKit uses extend(lst, other) to do a "list.extend" in Python terms.
Personally, I don't care what Prototype does. MochiKit exists because I didn't like anything they were doing at the time (and for the most part that's still true).
The only thing I'm emulating from Prototype is the $() function as an alias for MochiKit.DOM's getElement -- which I mostly discourage use of, but people seem happy enough using.
FWIW, your "append" might appeal to Scheme users, as that's almost what "append!" does (except it will take more than one argument) ;)
David: I agree very strongly that being able to extend Array.prototype is worth breaking the usability of for/in loops. And personally I see nothing wrong with extending Object.prototype as well. Being able to do these kind of things is one of the very cool features of Javascript.
Unfortunately, this destroys the usage of the otherwise elegant for/in loops. At least for the next decade, until all Javascript environments used in the wild will hopefully have a way to hide properties from the "in" operator.
Workaround for the next ten years:
for (i in obj) if (obj.propertyIsEnumerable(i)) foo(obj[i]);