0

If I have a javascript object like this:

{ 'apples':14, 'oranges': 1, 'bananas':4 }

How can I sort it to an Array, descending order, based on the value?

Result:

[ 'apples', 'bananas', 'oranges' ]

Because 14, 4, 1 ...descending order

TIMEX
  • 259,804
  • 351
  • 777
  • 1,080

3 Answers3

4

Pull all the keys from the object into an array and sort the array.

var o = { 'apples':14, 'oranges': 1, 'bananas':4 };
var a = [];

for (var key in o) {
    a.push(key);
}
a.sort();

If you think you need to protect against properties that have been added to the Object prototype in an unfriendly way (or don't know), then you should do it like this:

var o = { 'apples':14, 'oranges': 1, 'bananas':4 };
var a = [];

for (var key in o) {
    if (o.hasOwnProperty(key)) {
        a.push(key);
    }
}
a.sort();

EDIT: now that the original question has been changed and the requirement is now that the keys are sorted in order by the value in the original object, that would have to be done differently:

var o = { 'apples':14, 'oranges': 1, 'bananas':4 };
var a = [];

for (var key in o) {
    if (o.hasOwnProperty(key)) {
        a.push(key);
    }
}
a.sort(function(x, y) {return(o.y - o.x);});
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • 1
    Just an FYI: because of the way JavaScript objects are built, you should always wrap the inside of for-in loops with a `hasOwnProperty`: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/hasOwnProperty#section_8 – OverZealous Jul 31 '11 at 04:45
  • If it's your own code and you know what's going on and nobody has extended the object class with additional properties in an unfriendly way for the `for` loop, there's no need to wrap it. If you don't know everything that's going on in the project, then I'd agree it is safer to protect from stray properties. – jfriend00 Jul 31 '11 at 04:47
  • OK, I added the option for those who allow the object prototype to be messed with in their projects (something I don't allow). – jfriend00 Jul 31 '11 at 04:53
  • @jfriend00, thanks, but this doesn't do what I wanted to do, I think it was a misundersrtanding – TIMEX Jul 31 '11 at 04:53
  • It generates the EXACT output you asked for. It puts all the keys into an array and sorts them in the order you show them in your example. GEEZ, now I see you've changed the requirements by editing your post. You want them sorted by the values, not by the keys. – jfriend00 Jul 31 '11 at 04:55
  • That sorts it by key alphabetical descending, but not based on value – TIMEX Jul 31 '11 at 04:57
  • I added a new method that sorts the keys based on the value for the keys. – jfriend00 Jul 31 '11 at 05:03
  • FYI you don't have to cast to Number when you use subtraction. "Just sayin'" :-) – Ray Toal Jul 31 '11 at 05:18
  • @Ray Toal - thanks. I overlooked that they were actually already numbers, not strings. I edit to remove the cast. – jfriend00 Jul 31 '11 at 05:31
1

here is my approach to this problem:

var o={ 'apples':14, 'oranges': 1, 'bananas':4 };
var a=[];
for(var fruit in o)
{
   if(o[fruit])
      a[fruit]=o[fruit];  i.e // a[apples]=14;
}

a.sort(function(a,b){return Number(a)-Number(b);});

now a is sorted by the value.

console.log("Sorted Fruits:")
for(var fruit in o)
{
    if(o[fruit])
       console.log(fruit);
}
Baz1nga
  • 15,485
  • 3
  • 35
  • 61
  • But 'a' is not [ 'apples', 'bananas', 'oranges' ], an array. 'a' is [ apples: 14, oranges: 1, bananas: 4 ] – TIMEX Jul 31 '11 at 05:01
  • This generates an array of values which isn't what they asked for. After some discussion, it appears that they want an array of keys sorted in the order of the values for those keys. – jfriend00 Jul 31 '11 at 05:05
1

Here is the ES5 way to do it:

var fruit = { 'apples':14, 'oranges':1, 'grapefruit':70, 'bananas':4 }

var orderedByDescendingQuantities = Object.keys(fruit).sort(function (x, y) {
    return fruit[y] - fruit[x];
});

alert(orderedByDescendingQuantities);

See http://jsfiddle.net/gh5x8/

Ray Toal
  • 86,166
  • 18
  • 182
  • 232