views:

413

answers:

3

As a trivia question, I'm trying to write a javascript function that returns its variable number of arguments in sorted (normal lexicographic) order.

Having never dealt with javascript before, I came across the "arguments" object, which seems to work somewhat like an array but without having the standard array functions -- therefore I seem to need to copy its contents into a "real" array.

Is there a shorter/more concise way of doing this (preferably in a single line)?

function sortArgs() 
{
    args = new Array(); 
    for (var i = 0; i < arguments.length; i++) 
        args[i] = arguments[i]; 
    return args.sort();
}

UPDATE:
Brownie points for explaining how your answer works, since I'm new to JS. I understand slice(), but not the rest of it..

+13  A: 

Use:

function sortArgs() 
{
    var args = Array.prototype.slice.call(arguments, 0);
    return args.sort();
}

for brownie points:

Array.prototype.slice is the slice method belonging to all instances of Array as this is coming from the prototype (or cookie cutter) of Arrays.

.call and .apply can be used to apply a function from another object as if it were a part of the object being called upon.

OtherObj.prototype.someFuntion.call(yourobject,arg1) would use yourobject as this in someFunction. You're essentially changing the context of the function.

see: https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Function/apply and https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Function/call

Jonathan Fingland
Cool, thanks for the explanation.
Andrew Coleson
In recent Firefox versions (2.0?) and ECMAScript 5, there's an Array.slice method that make this a little simpler. You would call it like this: var arge = Array.slice(arguments, 0);.
Matthew Crumley
converting array-like objects to arrays via `slice()` unfortunately deson't work reliably across browsers - eg IE can't convert node lists this way; for a general function which works with all array-like objects, there's no way around manually looping over the entries
Christoph
What's the `0` for? Since there are no arguments you want to pass, why can't you just use `var args = Array.prototype.slice.call(arguments);` ? [ **The MDC arguments page** ](https://developer.mozilla.org/en/JavaScript/Reference/functions_and_function_scope/arguments) suggests the method without the `0`.
Peter Ajtai
@Christoph - IE should be able to convert `arguments`. This is because `arguments` has a properly set `length` property. As long as this is the case, the above method should work. (This works in IE 8: http://jsfiddle.net/6fyUT/ )
Peter Ajtai
+2  A: 

If you're using jQuery, the following is a good deal easier to remember in my opinion:

function sortArgs(){
  return $.makeArray(arguments).sort();
}
brad
That's essentially what I was looking for in pure JS, but +1 for the solid example of how jQuery makes JS a bit easier to grok.
Andrew Coleson
jquery?! the new MS
divinci
+3  A: 

To golf:

function sortArgs(){ return [].slice.call(arguments).sort() }

// Returns the arguments object itself
function sortArgs(){ return [].sort.call(arguments) }

Some array methods are intentionary made not to require the target object to be an actual array. They only require the target to have a property named length and indices (which must be zero or larger integers).

[].sort.call({0:1, 1:0, length:2}) // => ({0:0, 1:1, length:2})
matyr
Those are fun. You want to explain how they work?
Nosredna