Hi all I have an array of objects (20 of them) that I\'ve placed in this format to make columns in an Angular Project (note there are objects in objects). I want to sort the
Using a custom comparator for Array.prototype.sort
does what you need it to do
let data = [{a:1,b:2,c:3}, {a:1}, {a:1,b:2,c:3,d:4}, {a:1,b:2}]
data.sort((a,b) => Object.keys(a).length - Object.keys(b).length)
console.log(data)
If your data is nested, the child data should be attached to a property of a known name
let data = [
{foo: 'W', bar: {a:1,b:2,c:3}},
{foo: 'X', bar: {a:1}},
{foo: 'Y', bar: {a:1,b:2,c:3,d:4}},
{foo: 'Z', bar: {a:1,b:2}}
]
let keyToSort = "bar";
data.sort((a,b) => Object.keys(a[keyToSort]).length - Object.keys(b[keyToSort]).length)
console.log(data)
On the other hand, if it is guaranteed to always have exactly one key (perhaps with an unknown/dynamic name), you could write
Object.keys(a[Object.keys(a)[0]]).length
This however is obviously very ugly and error prone (what if it does have more keys - or none at all). If you have control over the data structure, you should think about refactoring it, since an Object with only one key makes not much sense - you could as well just drop one nesting level.
You should be in the habit of battling complexity — whenever it rears its stubborn head, grasp your staff and exert an equally stubborn force back upon it.
The first solution above appears somewhat manageable, but the second one starts to get pretty thick. If you break your solution down into tiny reusable parts, you can keep complexity at bay with relative ease.
const ascComparator = (a,b) => a < b ? -1 : a > b ? 1 : 0
// use this if you want to sort data descending instead of ascending
const descComparator = (a,b) => ascComparator(b,a)
const prop = x => y => y[x]
const len = prop('length')
const comp = f => g => x => f (g (x))
const keylen = comp (len) (Object.keys)
let data = [
{foo: 'W', bar: {a:1,b:2,c:3}},
{foo: 'X', bar: {a:1}},
{foo: 'Y', bar: {a:1,b:2,c:3,d:4}},
{foo: 'Z', bar: {a:1,b:2}}
]
// same as solution #2 but much more descriptive
// "sort ascending using keylen of a.bar compared to keylen of b.bar"
data.sort((a,b) => ascComparator(keylen(a.bar), keylen(b.bar)))
console.log(data)
Breaking complexity down is a way of investing in your future. Once you wrap a bit of complexity up in its own procedure, it will always be at your disposal at a later time. Smaller procedures are also easier to test.
Each of the procedures above ascComparator
, prop
, len
, comp
, and keylen
have immediately apparent intent. You can revisit these at any time and understand them with ease. And as a result of employing them, it makes your sort that much easier to read/write too.