I\'m having trouble figuring out from the lodash documentation if my assumption about sorting and grouping is correct.
If I use sortBy, then use groupBy, do the arrays p
It's not. Here's example, where order is not retained:
const data = [
{
item: 'item1',
group: 'g2'
}, {
item: 'item2',
group: 'g3'
}, {
item: 'item3',
group: 'g1'
}, {
item: 'item4',
group: 'g2'
}, {
item: 'item5',
group: 'g3'
}
]
const groupedItems = _(data).groupBy(item => item.group).value()
In this case one would expect that group order would be: g2, g3, g1 - reality is that they are sorted g1, g2, g3.
You can re-sort them with original array though.
const groupedItems = _(data)
.groupBy(item => item.group)
.sortBy(group => data.indexOf(group[0]))
.value()
This will ensure original order of items.
The current implementation of _.groupBy
is:
// An internal function used for aggregate "group by" operations.
var group = function(behavior) {
return function(obj, iteratee, context) {
var result = {};
iteratee = cb(iteratee, context);
_.each(obj, function(value, index) {
var key = iteratee(value, index, obj);
behavior(result, value, key);
});
return result;
};
};
// Groups the object's values by a criterion. Pass either a string attribute
// to group by, or a function that returns the criterion.
_.groupBy = group(function(result, value, key) {
if (_.has(result, key)) result[key].push(value); else result[key] = [value];
});
Basically it iterates through each of the items in the collection in order (if the collection is array-like, which it would be after a sortBy
), and pushes them to an array based on their key value.
So yes, I'm not sure if this is an "official" characteristic of _.groupBy
, but it does preserve the order of array-like collections, and that's probably unlikely to change.
Function groupBy returns object. Object doesn't save property order. Does JavaScript Guarantee Object Property Order?
But group arrays saves order, because thay are added with push function.