12

If I have this JS object literal:

var foo = {
    Sussy: 4,
    Billy: 5,
    Jimmy: 2,
    Sally: 1
};

How can I create a new, sorted object literal:

var bar = {
    Sally: 1,
    Jimmy: 2,
    Sussy: 4,
    Billy: 5
};
edt
  • 22,010
  • 30
  • 83
  • 118
  • 1
    You can't sort a JS Object as shown in your question. Impossible. Why? Because JS Object properties are not ordered. Switch to an array. Arrays are ordered, Objects are not. – Larry K Jun 07 '11 at 15:21

3 Answers3

12

Re: How to sort a JS Object?

Answer: You can't. So instead, you need a more sophisticated data structure. You have many options:

  1. You can use a separate array to hold the order of the object's keys. (This is what @Felix Kling's answer demonstrates.) Good: fast retrieval via order or name. Bad: needs a second data structure that must be kept synched with the first.
  2. Instead of the Object simply holding properties and values, the properties could hold Objects which hold the values and a sort order. Good: 1 data structure. Fast lookup by property name. Bad: slow lookup by order (need to scan the structure). Slow sorting.
  3. Use an array, with elements consisting of Objects that hold the key and the value. Good: 1 data structure. Fast lookup by order. Fast sorting. Bad: slow lookup by property name (need to scan the structure).

I recommend solution 3 since it uses the JS mechanics to manage the ordering.

Examples:

// Object holds sort order:  (Solution 2)
var foo = {
  Suzy: {v: 4, order: 0},
  Billy: {v: 5, order: 1},
  Jimmy: {v: 2, order: 2},
  Sally: {v: 1, order: 3}
};    

// Array holds keys: (Solution 3)
var woof = [
  {k: 'Suzy', v: 4},
  {k: 'Billy', v: 5},
  {k: 'Jimmy', v: 2},
  {k: 'Sally', v: 1}
];

// Sort the woof array by the key names:
woof.sort(function(a, b) {
  return a.k.localeCompare(b.k);
});

// The third key and value:
woof[2].k; // the third key
woof[2].v; // the third value

Edited: updated code to fix typo. Thank you, @Martin Fido

Larry K
  • 47,808
  • 15
  • 87
  • 140
  • Thanks for putting me on the right track and all the details. I will try #3. – edt Jun 08 '11 at 15:18
  • 1
    Thanks for this, I like 3 also. Note however that the sort doesn't seem to work. Try woof.sort(function(a, b) { return a.k.localeCompare(b.k); }); – Martin Fido Oct 31 '12 at 10:26
  • I create a huge Object literal from a JSON structure. My problem is i have to add properties to nested Objects between other properties. i gave them id's but it's not very good because i have to recursively loop through all the nodes and its children. could you suggest a special data structure? maybe storing Objects references in an orderArray ? – philx_x Mar 11 '15 at 15:41
  • @philx_x You should ask your question as a new question on stack overflow – Larry K Mar 12 '15 at 06:41
8

Object properties are in no specific order (the order is implementation dependent) and you cannot sort the properties.

You have to keep an array of keys and sort it accordingly, for example:

var keys = [];

for(var key in obj) {
    if(obj.hasOwnProperty(key)) {
        keys.push(key);
    }
}

keys.sort(function(a, b) {
    return obj[a] - obj[b];
});

Now you can iterate over the values of the array and use them to access the corresponding property of the object.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
1

Turns out object property order is predictable since ES2015. Which is amazing.

Check it out here.

  • Does that mean you can show how to sort the object? – Scratte Nov 25 '20 at 22:28
  • 1
    This is a link only answer. Either extract or intrepid the info needed and add it to the answer. Link only answers are undesirable because they are useless when the link goes down. As a rule of thumb an answer should always hold up by itself without relying on external information. Adding a snippet showcasing how you would sort an object would help this answer a great deal. – 3limin4t0r Nov 25 '20 at 23:03