问题
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 produced by groupBy maintain the sort order of items?
For example, say I have the following array:
var testArray = [[5,6],[1,3],[5,4],[5,1]]
And I would like to group these by their first element, but also have them sorted by their second element within these groups. So, in lodash I assume I can do the following:
_.chain(testArray)
.sortBy(function (item) { return item[1]; })
.groupBy(function (item) { return item[0]; })
.value()
Which ends up producing what I would expect it to:
{
1: [[1,3]]
5: [[5,1],[5,4],[5,6]]
}
Is this just coincidence? Is there anything about how sortBy and groupBy work that ensures this ordering of the grouped arrays? The documentation says that sortBy is a stable sort, does that in the same way apply to groupBy? Is there any reason I should not assume this will work every time?
回答1:
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.
回答2:
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.
回答3:
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.
来源:https://stackoverflow.com/questions/28860526/lodash-sortby-then-groupby-is-order-maintained