0

I have the following code to generate a simple Hash array.

function getRandomArbitrary(min, max) {
    return Math.random() * (max - min) + min;
}
var arr = [];
for (i=0; i<10; i++) {
    var id = 'user-' + Math.floor(getRandomArbitrary(0,1000));
    var xp = Math.floor(getRandomArbitrary(2000,3000));
    arr[id] = ({'xp':xp});
}

Now to loop through the array I do:

for (id in arr) {
    document.write(id + ': ' + arr[id].xp + '<br>');
}

An example result would be:

user-750: 2085
user-681: 2051
user-790: 2174
user-542: 2537
user-943: 2913
user-678: 2829
user-365: 2398
user-886: 2571
user-635: 2525
user-786: 2482

This will show all users and their XP.

The question is, how can I sort this array by XP (descending) ?

I started with:

arr = arr.sort(function(a,b) {
    return b.xp - a.xp;
});

But that doesn't work well.

3
  • 1
    why it doesn't work 'well'? Commented Aug 16, 2014 at 8:42
  • It didn't sort by XP. Commented Aug 16, 2014 at 8:45
  • arr isn't an array, it's an object. An array has numeric keys, and .sort only operates on those elements. Commented Aug 16, 2014 at 8:48

3 Answers 3

4

You can't sort it because you are not using the array as an array.

An array is also an object, that is why you can add items to it with a key like "user-750". Those items are however properties in the array object, they are not items in the array. When you sort the array, it will only sort the items, and there are no items in the array so the sorting won't change anything.

You can't sort the properties, as the order of the properties are undefined. If you try to add the properties in a specific order, they will still be returned in an order depending on how they are stored internally. This is implementation specific, and different browsers will actually return the properties in different order.

If you want to sort the array, you have to add the objects as items in the array, not as properties:

arr.push({ id: id, xp: xp });
Sign up to request clarification or add additional context in comments.

2 Comments

This is what I did before, but what if I want to lookup the XP for a specific ID, would I have to loop through the array?
@P.Henderson: Yes, you can't have both, unless you actually have both. You can have an array for the order and an object for the lookup.
1

Your 'array' is not an array, but an object:

{ 
  'user-750': {xp: 2085}
  'user-681': {xp: 2051}
  ...
}

If you want to sort, you need an array of objects:

[
 {id: 'user-750', xp: 2085},
 {id: 'user-681', xp: 2051},
  ...
]

That array of objects should be sortable.

Here's a home brew sorter method I use for sorting (demonstrated in this jsFiddle):

function sorter(sortOn,descending) {
    sortOn = sortOn && sortOn.constructor === Object ? sortOn : {};
    return function ( a, b ) {
        if (sortOn.string || sortOn.numeric || sortOn.key) {
            a = sortOn.key ? a[sortOn.key] : a;
            a = sortOn.string ? String(a) : sortOn.numeric ? +a : a;
            b = sortOn.key ? b[sortOn.key] : b;
            b = sortOn.string ? String(b) : sortOn.numeric ? +b : b;
            if (sortOn.key && (!b || !a)) { //empty values on top
                return !a && !b ? 1 : !a ? 1 : -1;
            }
        }
        return descending 
                ? (a < b ? 1 : a > b ? -1 : 0)
                : (a < b ? -1 : a > b ? 1 : 0);

    };
}
// usage
arr = arr.sort( sorter({key: 'xp', numeric: 1}, true) );

Comments

0

I think you have to set your priority.

1) If you want to sort your records, you can use array. But for looking an specific key you have to go through key.

2) If you want to get records by key, you can use an object/hash for that, but then you cann't sort your records, There is no specific order in hash.

If you are going using array & sorting, I think you should change your implementation a bit while are you pushing things in array.

Like bellow

arr.push({ id: id, xp: xp });

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.