Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to sort/order keys in JavaScript objects?

Tags:

javascript

For example the following

var data = {
    'States': ['NSW', 'VIC'],
    'Countries': ['GBR', 'AUS'],
    'Capitals': ['SYD', 'MEL']
}
for (var item in data) {
    console.log(item);
}

prints

States
Countries
Capitals

Is there a way to sort alphabetically so that it prints

Capitals
Countries
States
like image 725
Hoa Avatar asked Mar 11 '12 20:03

Hoa


People also ask

Can you assume the order of keys in an object?

YES (but not always insertion order). Most Browsers iterate object properties as: Integer keys in ascending order (and strings like "1" that parse as ints) String keys, in insertion order (ES2015 guarantees this and all browsers comply) Symbol names, in insertion order (ES2015 guarantees this and all browsers comply)

How do I sort a JSON key?

Enter your JSON into the first text area, or drag and drop a file, after, select the sort method you're going to use, key value requires the key name (if not specified selects the first key), click the example button to get an idea on how it works. The result will automatically sort and display in the output text area.

Why does JavaScript automatically sort the number keys in an object?

Because JavaScript sucks. To preserve insertion order, either prepend leading zeros to each numeric key (since parseInt() won't mind those), or use an ES6 Map instead of an object.

How do you sort an object in an object?

const obj = { "CAB": { name: 'CBSSP', position: 2 }, "NSG": { name: 'NNSSP', position: 3 }, "EQU": { name: 'SSP', position: 1 } };


4 Answers

Not within the object itself: the property collection of an object is unordered.

One thing you could do is use Object.keys(), and sort the Array, then iterate it.

Object.keys(data)
      .sort()
      .forEach(function(v, i) {
          console.log(v, data[v]);
       });

Patches (implementations) for browsers that do not support ECMAScript 5th edition:

  • Object.keys

  • Array.forEach

like image 62
5 revs, 2 users 83%user1106925 Avatar answered Oct 09 '22 09:10

5 revs, 2 users 83%user1106925


here's a nice functional solution:

basically,

  1. extract the keys into a list with Object.keys
  2. sort the keys
  3. reduce list back down to an object to get desired result

ES5 Solution:

not_sorted = {b: false, a: true};

sorted = Object.keys(not_sorted)
    .sort()
    .reduce(function (acc, key) { 
        acc[key] = not_sorted[key];
        return acc;
    }, {});

console.log(sorted) //{a: true, b: false}

ES6 Solution:

not_sorted = {b: false, a: true}

sorted = Object.keys(not_sorted)
    .sort()
    .reduce((acc, key) => ({
        ...acc, [key]: not_sorted[key]
    }), {})

console.log(sorted) //{a: true, b: false}
like image 31
mac Avatar answered Oct 09 '22 08:10

mac


Yes, there is. Not within ECMAScript standard, but supported across browsers and Node.js, and apparently stable. See https://stackoverflow.com/a/23202095/645715.

EDIT: This returns an object in which the keys are ordered. You can use Object.keys(...) to get the ordered keys from the object.

Why worry about object key order? The difference can matter in some applications, such as parsing XML with xml2js which represents XML as nested objects, and uses XML tags as hash keys.

There are a couple of notes:

  • keys that look like integers appear first and in numeric order.
  • keys that look like strings appear next and in insertion order.
  • this order is reported by Object.keys(obj)
  • the order as reported by for (var key in obj) {...} may differ in Safari, Firefox

The function returns an object with sorted keys inserted in alphabetic order:

function orderKeys(obj) {

  var keys = Object.keys(obj).sort(function keyOrder(k1, k2) {
      if (k1 < k2) return -1;
      else if (k1 > k2) return +1;
      else return 0;
  });

  var i, after = {};
  for (i = 0; i < keys.length; i++) {
    after[keys[i]] = obj[keys[i]];
    delete obj[keys[i]];
  }

  for (i = 0; i < keys.length; i++) {
    obj[keys[i]] = after[keys[i]];
  }
  return obj;
}

Here's a quick test:

var example = { 
      "3": "charlie",
      "p:style": "c",
      "berries": "e",
      "p:nvSpPr": "a",
      "p:txBody": "d",
      "apples": "e",
      "5": "eagle",
      "p:spPr": "b"
    }

var obj = orderKeys(example);

this returns

{ '3': 'charlie',
  '5': 'eagle',
  apples: 'e',
  berries: 'e',
  'p:nvSpPr': 'a',
  'p:spPr': 'b',
  'p:style': 'c',
  'p:txBody': 'd' }

You can then get the ordered keys as:

Object.keys(obj) 

Which returns

["3", "5", "apples", "berries", "p:nvSpPr", "p:spPr", "p:style", "p:txBody"]
like image 19
prototype Avatar answered Oct 09 '22 07:10

prototype


You can also sort it in this way.

const data = {
  States: ['NSW', 'VIC'],
  Countries: ['GBR', 'AUS'],
  Capitals: ['SYD', 'MEL']
}

const sortedObject = Object.fromEntries(Object.entries(data).sort())

I cannot explain in detail why it works but apparently it's working flawlessly :) Try yourself if you're not believing me :D

Note that your browser or Node.js version should support Object.fromEntries

For browser compatibility check bottom of this page

For Node, it will work for versions from 12 and higher. For Deno from the v1.

like image 10
Andrii Los Avatar answered Oct 09 '22 09:10

Andrii Los