I know my question title can be confusing (I'm aware object properties don't have an order) since I'm already proposing a solution with it, so to avoid creating an XY problem, let me first explain my goal:
I need to render N tables of words grouped by word length and (this is the tricky thing) ordered by length in descending order . Something like:
Words with length 4
===================
abcd | other fields
abce | other fields
abcf | other fields
Words with length 3
===================
abc | other fields
abd | other fields
abe | other fields
Words with length 2
===================
...
I'm getting my list of words from an API without any grouping, so what I'm doing right now is:
let grouped = {};
// Assume words is an Array of words of multiple lengths
words.forEach(w => {
if (typeof grouped[w.length] === 'undefined')
grouped[w.length] = [];
grouped[w.length].push({'word': w});
// Pushing an object cause of other calculated and not rellevant fields
});
Of course, when I render this grouped
words (I'm using Vue.js)...
<WordsTable
v-for="(group, length) in grouped"
:words="group"
:word-length="length"
/>
I use the word-length
prop to render the table's header saying Words with length N.
Everything works but I get the tables in ascending order (and, again, I'm aware this might be a coincidence because there's no order in objects). So the real question is, can anybody figure out a way so that Vue iterates my grouped
object with descending sorted keys?
Note: There might not be words of some specific lengths, so maybe Object.keys(grouped)
is [3,4,7,9,10]
UPDATE:
A commenter suggests using an Array instead of an Object for grouped
. I already tried and it's true that might be slightly better but doesn't completely solve the problem.
If grouped
is an array, I can reverse it:
<WordsTable
v-for="(group, length) in grouped.reverse()"
...
/>
But in this case, indexes are lost and can no longer be used to render the table's header title.
You can create a computed property that sorts your object keys in a descending order:
sortedGroupKeys() {
return Object.keys( group ).sort( ( a , b ) => b - a );
}
then you can loop though it.
<WordsTable
v-for="(key in sortedGroupKeys)"
:words="group[ key ]"
:word-length="key"
/>
Hope this helps.