Reputation: 648
Can someone please help to figure out the way to sort a dictionary with another dictionary inside in JavaScript? This is how my dict looks like:
{'POS2': {'stegano': 0, 'sum': 200, 'misc': 100, 'web': 0, 'ppc': 0, 'crypto': 0, 'admin': 0, 'vuln': 0, 'forensics': 0, 'hardware': 0, 'reverse': 0, 'recon': 100}, ...}
I want to sort it by 'sum' key that is stored in nested dict. I can find some solutions written in python, but the challenge here is to achieve the same functionality in JS. Would appreciate any help.
Upvotes: 0
Views: 1733
Reputation: 1010
For example, you have next array (similar to your array, but has less properties to readable):
let obj = {
pos1: { sum: 100, name: 'p1' },
pos2: { sum: 1, name: 'p2' },
pos3: { sum: 50, name: 'p3' }
};
var result = Object.keys(obj)
.map(key => { return {key, val: obj[key]}}) // output: unsorted array
.sort((a, b) => a.val.sum > b.val.sum);
console.log(result);
and as result you will see:
[ { key: 'pos2', val: { sum: 1, name: 'p2' } },
{ key: 'pos3', val: { sum: 50, name: 'p3' } },
{ key: 'pos1', val: { sum: 100, name: 'p1' } } ]
Upvotes: 0
Reputation: 63524
Since you can't order objects by property you'd need to map
the objects to an array and then sort that. And you'd probably not want to lose the key for each nested object (like POS2), so you'd want to embed that key in the object for safe-keeping.
const obj = {"POS2":{"stegano":0,"sum":2200,"misc":100,"web":0,"ppc":0,"crypto":0,"admin":0,"vuln":0,"forensics":0,"hardware":0,"reverse":0,"recon":100},"POS3":{"stegano":0,"sum":1200,"misc":100,"web":0,"ppc":0,"crypto":0,"admin":0,"vuln":0,"forensics":0,"hardware":0,"reverse":0,"recon":100},"POS4":{"stegano":0,"sum":22,"misc":100,"web":0,"ppc":0,"crypto":0,"admin":0,"vuln":0,"forensics":0,"hardware":0,"reverse":0,"recon":100},"POS5":{"stegano":0,"sum":2001,"misc":100,"web":0,"ppc":0,"crypto":0,"admin":0,"vuln":0,"forensics":0,"hardware":0,"reverse":0,"recon":100}}
// map over the object keys
const out = Object.keys(obj).map(key => {
// on each iteration return the object with its new key property
return { ...obj[key], key }
// then sort the array of object by their sums
}).sort((a, b) => a.sum - b.sum);
console.log(out);
Upvotes: 0
Reputation: 12796
Just retrieve the inner object using Object.values
and then use Array.sort
to sort by it's content. Note that you cannot sort an objects properties as they are per default an unsorted set (or at least, it's not properly described how properties should be sorted on an object)
const dict = {
'POS2': {
'stegano': 0,
'sum': 200,
'misc': 100,
'web': 0,
'ppc': 0,
'crypto': 0,
'admin': 0,
'vuln': 0,
'forensics': 0,
'hardware': 0,
'reverse': 0,
'recon': 100
},
'POS1': {
'sum': 100
},
'POS3': {
'sum': 250
}
};
function orderBySubKey( input, key ) {
return Object.values( input ).map( value => value ).sort( (a, b) => a[key] - b[key] );
}
console.log( orderBySubKey( dict, 'sum' ) );
This sample would remove the outer properties, if you want to keep these, you can change your ordering a bit, for example like
const dict = {
'POS2': {
'stegano': 0,
'sum': 200,
'misc': 100,
'web': 0,
'ppc': 0,
'crypto': 0,
'admin': 0,
'vuln': 0,
'forensics': 0,
'hardware': 0,
'reverse': 0,
'recon': 100
},
'POS1': {
'sum': 100
},
'POS3': {
'sum': 250
}
};
function orderBySubKey( input, key ) {
return Object.keys( input ).map( key => ({ key, value: input[key] }) ).sort( (a, b) => a.value[key] - b.value[key] );
}
console.log( orderBySubKey( dict, 'sum' ) );
Which gives you a different output, but would still allow you to lookup inside the original dictionary
Upvotes: 2