Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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..

share|improve this question

5 Answers

up vote 55 down vote accepted

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

share|improve this answer
Cool, thanks for the explanation. – Andrew Coleson Jun 7 '09 at 0:42
1  
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 Jun 7 '09 at 2:06
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 Jun 7 '09 at 15:13
2  
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 ](developer.mozilla.org/en/JavaScript/Reference/…) suggests the method without the 0. – Peter Ajtai Oct 5 '10 at 17:56
@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: jsfiddle.net/6fyUT ) – Peter Ajtai Oct 5 '10 at 18:02

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})
share|improve this answer
Those are fun. You want to explain how they work? – Nosredna Jun 9 '09 at 18:36

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

function sortArgs(){
  return $.makeArray(arguments).sort();
}
share|improve this answer
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 Jun 7 '09 at 0:21
jquery?! the new MS – divinci Jun 7 '09 at 1:10

Can you not just call arguments.sort()? (Or was the whole purpose to clone the elements)

share|improve this answer
2  
No, this is not possible, because arguments is not an array and only arrays have this method. – Felix Kling Feb 22 '11 at 16:21

if you're doing more than one thing to your newly Array arguments, and you're into brevity, you can do:

var a = [].concat(arguments);

To make an array out of the arguments, then do whatever to the array. [].concat is shorter than Array.prototype.whatever.call.

share|improve this answer
3  
This doesn't work. [].concat(arguments) creates an array with one element -- the Arguments object. – Leopd May 11 '12 at 0:21

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.