Reputation: 793
I have some json in the form of:
data = {
"1": {"name": "eve", "type": "sergeant", "age": 22},
"2": {"name": "bob", "type": "sergeant", "age": 33},
"3": {"name": "bats", "type": "private", "age": 90},
"4": {"name": "carol", "type": "captain", "age": 50},
"5": {"name": "noogle", "type": "sergeant", "age": 34},
"6": {"name": "good", "type": "sergeant", "age": 47},
"7": {"name": "alice", "type": "private", "age": 34}
}
How can I groupBy
their type
, and then within each type, they are sorted by their name in ascending order?
I tried to do it with:
let grouped = _.groupBy(Object.keys(data), function(id) {
return data[id].type;
});
Which will give me something like:
{
"sergeant": ["1", "2", "5", "6"],
"private": ["3", "7"],
"captain": ["4"]
}
But when I try to sortBy
it gives me the same object as above:
_.map(Object.keys(grouped), function(type_name) {
grouped[type_name] = _.sortedBy(grouped[type_name], function(id) {
return data[id].name;
});
});
How can I sort the array after I've grouped the objects together? Is there a way I can cleanly chain groupBy
and sortBy
together instead of splitting logic like I have above?
Upvotes: 3
Views: 6732
Reputation: 32186
You can use the _.mapValues
method to sort each group after you've grouped them up by using _.groupBy
. Just take each value and return the sorted version of it in your _.mapValues
callback function.
Example:
data = {
"1": {"name": "eve", "type": "sergeant", "age": 22},
"2": {"name": "bob", "type": "sergeant", "age": 33},
"3": {"name": "bats", "type": "private", "age": 90},
"4": {"name": "carol", "type": "captain", "age": 50},
"5": {"name": "noogle", "type": "sergeant", "age": 34},
"6": {"name": "good", "type": "sergeant", "age": 47},
"7": {"name": "alice", "type": "private", "age": 34}
}
console.log(_.mapValues(_.groupBy(data, "type"), v => _.sortBy(v, "name")))
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
Or, if you just want grouped and sorted keys, or grouped and sorted key/values, you can use the same approach, although its not quite as easy on the eyes:
data = {
"1": {"name": "eve", "type": "sergeant", "age": 22},
"2": {"name": "bob", "type": "sergeant", "age": 33},
"3": {"name": "bats", "type": "private", "age": 90},
"4": {"name": "carol", "type": "captain", "age": 50},
"5": {"name": "noogle", "type": "sergeant", "age": 34},
"6": {"name": "good", "type": "sergeant", "age": 47},
"7": {"name": "alice", "type": "private", "age": 34}
}
// If all you want are grouped and sorted keys:
console.log(_.mapValues(_.groupBy(_.keys(data), k => data[k].type), v => _.sortBy(v, i => data[i].name)))
// Or for grouped and sorted keys and values:
console.log(_.mapValues(_.groupBy(_.keys(data), k => data[k].type), v => _.sortBy(v, i => data[i].name).map(k => ({[k]: data[k]}))))
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
Upvotes: 5