Reputation: 734
In order to make stats and use some charts in a project, I use .groupBy()
method from Lodash.
It’s some sort of counting a number of shops in countries.
Long story short, I have a long array of objects (shops) with a country property on them, and just basically group them like this:
const countries = groupBy(shops, shop => shop[country])
Which results in this output (object type):
{
Austria: [{...}, {...}, {...}, {...}],
Canada: [{...}, {...}],
Italy: [{...}],
Japan: [{...}, {...}, {...}, {...}, {...}, {...}]
}
Indeed, it’s not sorted in any way, it’s just the order of the raw data came in the loop. And I need to sort it somehow, to obtain this:
{
Japan: [{...}, {...}, {...}, {...}, {...}, {...}],
Austria: [{...}, {...}, {...}, {...}]
Canada: [{...}, {...}],
Italy: [{...}]
}
I naturally looked up with .orderBy()
method, but it outputs an array, and I’m losing the key names:
const sortedCountries = orderBy(countries, countries.length, 'desc')
[
[{...}, {...}, {...}, {...}, {...}, {...}],
[{...}, {...}, {...}, {...}]
[{...}, {...}],
[{...}]
]
This is not useable in this state. I need to keep the original object format and to keep the keys (country names).
I know and found a few ways to sort objects by key values, but it always require the key name to be consistent each time, which is not the case here.
I’m lost at this point. Tried too much things to keep track, but nothing getting close to success. Any help welcome! Thanks.
If you’re wondering why I want to get this ordering stuff, it’s because in the charts, I need to keep the 4 first (highests) countries, and then group all the others again in a single "other" category.
It’s all going within a for loop just after the previous chunks of code, like this:
const props = Object.keys(countries)
for (const prop in props) {
const labelText = prop // This is the country name we got in the object
const value = countries[prop].length || 0
}
And sent directly into the charts class later, so at this point, within the loop, I won’t be able to sort anything.
Or do I? If there’s a way for this that I couldn't think of, please let me know.
Thanks!
EDIT: I’m slowly starting to assume that JS will render an object by sorting the keys by alphabetical order no matter what, which would make my request here totally pointless… Anyone can confirm?
Upvotes: 1
Views: 117
Reputation: 481
You can write a simple code for that.
const sortedKeys = Object.keys(countries).sort((k1, k2) => countries[k2].length - countries[k1].length);
In case sortedKeys are not enough, you can reconstruct the object based on it.
const sortedCountries = sortedKeys.reduce((acc, cur) => {
acc[cur] = countries[cur];
return acc;
}, {});
Enjoy!
Upvotes: 2