tags:

views:

73

answers:

2

How easy/hard is it to order collections in javascript (alphabetical and numerically).

Say I have a collection like:

var map = {

    user: { id: "23434", username: "mrblah" },
    user: { id: "1010", username: "johnskeet" }

};

And I want to order the collection by id and username.

Update correction thanks:

var map = [ { id: "23434", username: "mrblah" }, { id: "1010", username: "johnskeet" } ];
+3  A: 
var map = { 
    users: [
        { id: "23434", username: "mrblah" },
        { id: "1010", username: "johnskeet" }
    ]
};

map.users.sort(function(a, b) { 
    return a.id - b.id; 
});

map.users.sort(function(a, b) { 
    return a.username.localeCompare(b.username); 
});
ChaosPandion
should it be: map.users.sort = function(....) and then ?
mrblah
What is this `compareTo` you speak?
Crescent Fresh
Fixed, nice catch.
ChaosPandion
compareTo() is a JavaScript function I don't recognize. Is that a Java convention?
artlung
@mrblah - Negative, you pass the compare function as the argument.
ChaosPandion
I think if you just pass in `function(a, b) { return (a.username > b.username); }` into `map.users.sort()` -- my example does that.
artlung
As @ChaosPandion pointed out, my `a.username > b.username` is no good. Use `a.username.localeCompare(b.username)` in the comparison function
artlung
A: 

You want your object to be an array:

var map = [
    { id: "23434", username: "mrblah" },
    { id: "1010", username: "johnskeet" },
    { id: "1220", username: "alohaguy" }
];

We need a utility to display the usernames in order so we can test our work:

var displayUsernames = function(map) {
    var out = [];
    for (var i=0;i<map.length;i++) {
     out.push((map[i].username));
    }
    alert(out.join(', '));
};

If we use it: displayUsernames(map); we get mrblah, johnskeet, alohaguy

Since it's an array, so we can use .sort(), like this: map.sort();, but if we do that we still get:

mrblah, johnskeet, alohaguy

...from displayUsernames(map); because the array of objects can't be sorted the same way as if it were an array of numbers or strings.

However, if we pass the sort() function a comparison function...

var myCompareFunction = function(a, b) {
    return a.username.localeCompare(b.username);
};

Then pass it into map.sort()

map.sort(myCompareFunction);

Now, when we display it again with displayUsernames(map); we get alohaguy, johnskeet, mrblah

Hope that helps.

artlung
The compare function should not return a boolean. https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/sort
ChaosPandion
@ChaosPandion - thanks, learn something every day! I changed it from `a.username > b.username` to `a.username.localeCompare(b.username);`
artlung
I cannot up-vote you, can you make some kind of modification to your answer?
ChaosPandion
@ChaosPandio - I did modify my answer: http://stackoverflow.com/revisions/1678007/list ... based on your feedback.
artlung
Weird... this may be bug in the vote system.
ChaosPandion
I'm just happy to have learned about `localeCompare()` :-)
artlung
@artlung: don't be too happy: http://michael.susens-schurter.com/blog/tag/localecompare/
Crescent Fresh
@CrescentFresh hmm. Interesting, sad. I wonder how it would look if you did toLowerCase() on the strings then took the character code. Bizarre behavior. :-( Any other suggestions for sorting comparisons?
artlung