2

I have this nested object which I want to sort alphabetically,

var obj = {
  'ABCD' : {
    'E' : {},
    'R' : {},
    'A' : {},
    'E' : {}
  },
  'WXYZ' : {
    'F' : {},
    'M' : {},
    'G' : {},
    'A' : {}
  },
  'MNOP' : {
    'A' : {},
    'H' : {},
    'B' : {},
    'C' : {}
  },
  'EFGH' : {
    'D' : {},
    'C' : {},
    'B' : {},
    'E' : {}
  }
}

I want the output to be like this-

{
  'ABCD' : {
    'A' : {},
    'E' : {},
    'E' : {},
    'R' : {}
  },
  'EFGH' : {
    'B' : {},
    'C' : {},
    'D' : {},
    'E' : {}
  },
  'MNOP' : {
    'A' : {},
    'B' : {},
    'C' : {},
    'H' : {}
  },
  'WXYZ' : {
    'A' : {},
    'F' : {},
    'G' : {},
    'M' : {}
  }
}

I have written code to sort direct keys, but I am not getting how can I sort further object within those keys, Here's my code-

var sorted = {}
Object.keys(obj).sort().forEach(function(val) {
  sorted[val] = obj[val]
})

Please suggest on how can I achieve the output mentioned above. Thanks.

Vivek kumar
  • 1,632
  • 1
  • 14
  • 29
  • possible duplicate of https://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order you could try to use an array instead – Krzysztof Krzeszewski Feb 25 '19 at 07:08
  • 1
    Note: if you have any integer keys, then they'll be sorted to the top irrespective of the order in which the keys were added to the object [Does JavaScript Guarantee Object Property Order?](https://stackoverflow.com/questions/5525795) – adiga Feb 25 '19 at 07:10
  • Object properties **can not be ordered** – FZs Feb 25 '19 at 07:12
  • @FZs They can be in ES6. The order is: 1) integer keys 2) all other string keys, in the order in which they were added 3) all symbol keys http://2ality.com/2015/10/property-traversal-order-es6.html#traversing-the-own-keys-of-an-object – adiga Feb 25 '19 at 07:15
  • @adiga Ok, but is it possible to sort keys inside '*all other string keys*'? – FZs Feb 25 '19 at 07:44
  • @FZs what OP is asking is create a new with the sorted keys. Then they'll be returned *in the order in which they were added* – adiga Feb 25 '19 at 07:58

3 Answers3

4

You could take an recursive approach for nested objects.

const
    sort = o => Object.assign({}, ...Object
        .keys(o)
        .sort()
        .map(k => ({ [k]: o[k] && typeof o[k] === 'object' ? sort(o[k]) : o[k] }))
    );

var obj = { ABCD: { E: { }, R: { }, A: { } }, WXYZ: { F: { }, M: { }, G: { }, A: { } }, MNOP: { A: { }, H: { }, B: { }, C: { } }, EFGH: { D: { }, C: { }, B: { }, E: { } } },
    sorted = sort(obj);

console.log(sorted);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 323,592
  • 20
  • 270
  • 324
1

Assign an empty object first, and add sorted properties.

var sorted = {}
Object.keys(obj).sort().forEach(function(val) {
  sorted[val] = {}
  Object.keys(obj[val]).sort().forEach(function(val2) {
    sorted[val][val2] = obj[val][val2]
  })
})

Complete snippet:

var obj = {
  'ABCD': {
    'E': {},
    'R': {},
    'A': {},
    'E': {}
  },
  'WXYZ': {
    'F': {},
    'M': {},
    'G': {},
    'A': {}
  },
  'MNOP': {
    'A': {},
    'H': {},
    'B': {},
    'C': {}
  },
  'EFGH': {
    'D': {},
    'C': {},
    'B': {},
    'E': {}
  }
}

var sorted = {}
Object.keys(obj).sort().forEach(function(val) {
  sorted[val] = {}
  Object.keys(obj[val]).sort().forEach(function(val2) {
    sorted[val][val2] = obj[val][val2]
  })
})
console.log(sorted)
zmag
  • 6,257
  • 12
  • 26
  • 33
0

Recursive version

function sortedFunc(inputObj){
    var sorted = {}

    //get keys
    const keys = Object.keys(inputObj).sort();
    keys.forEach( key => {
       if(inputObj[key] instanceof Object){           
           sorted[key] = sortedFunc(inputObj[key]);
       } else {
           sorted[key] = inputObj[key];
    }
});
return sorted;
}