lodash sortBy 然后 groupBy,顺序是否保持?
lodash sortBy then groupBy, is order maintained?
我无法根据 lodash 文档确定我关于排序和分组的假设是否正确。
如果我使用 sortBy,然后使用 groupBy,groupBy 生成的数组是否保持项目的排序顺序?
例如,假设我有以下数组:
var testArray = [[5,6],[1,3],[5,4],[5,1]]
我想按第一个元素对它们进行分组,但也希望按这些组中的第二个元素对它们进行排序。因此,在 lodash 中,我假设我可以执行以下操作:
_.chain(testArray)
.sortBy(function (item) { return item[1]; })
.groupBy(function (item) { return item[0]; })
.value()
这最终产生了我期望的结果:
{
1: [[1,3]]
5: [[5,1],[5,4],[5,6]]
}
这只是巧合吗?关于 sortBy 和 groupBy 的工作方式是否有任何内容可以确保分组数组的这种排序?文档说 sortBy 是一种稳定的排序,这是否同样适用于 groupBy?有什么理由我不应该假设这每次都有效吗?
_.groupBy
的current implementation是:
// 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];
});
基本上它按顺序遍历集合中的每个项目(如果集合是类似数组的,它将在 sortBy
之后),并根据它们的键将它们推送到数组值。
所以是的,我不确定这是否是 _.groupBy
的 "official" 特征,但它确实保留了类数组集合的顺序,而且这可能不太可能改变。
函数 groupBy returns 对象。对象不保存 属性 顺序。
Does JavaScript Guarantee Object Property Order?
但是组数组可以节省顺序,因为它们添加了推送功能。
不是。这是不保留顺序的示例:
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()
在这种情况下,人们会期望组顺序为:g2、g3、g1 - 实际情况是它们按 g1、g2、g3 排序。
虽然你可以用原始数组重新排序它们。
const groupedItems = _(data)
.groupBy(item => item.group)
.sortBy(group => data.indexOf(group[0]))
.value()
这将确保项目的原始顺序。
我无法根据 lodash 文档确定我关于排序和分组的假设是否正确。
如果我使用 sortBy,然后使用 groupBy,groupBy 生成的数组是否保持项目的排序顺序?
例如,假设我有以下数组:
var testArray = [[5,6],[1,3],[5,4],[5,1]]
我想按第一个元素对它们进行分组,但也希望按这些组中的第二个元素对它们进行排序。因此,在 lodash 中,我假设我可以执行以下操作:
_.chain(testArray)
.sortBy(function (item) { return item[1]; })
.groupBy(function (item) { return item[0]; })
.value()
这最终产生了我期望的结果:
{
1: [[1,3]]
5: [[5,1],[5,4],[5,6]]
}
这只是巧合吗?关于 sortBy 和 groupBy 的工作方式是否有任何内容可以确保分组数组的这种排序?文档说 sortBy 是一种稳定的排序,这是否同样适用于 groupBy?有什么理由我不应该假设这每次都有效吗?
_.groupBy
的current implementation是:
// 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];
});
基本上它按顺序遍历集合中的每个项目(如果集合是类似数组的,它将在 sortBy
之后),并根据它们的键将它们推送到数组值。
所以是的,我不确定这是否是 _.groupBy
的 "official" 特征,但它确实保留了类数组集合的顺序,而且这可能不太可能改变。
函数 groupBy returns 对象。对象不保存 属性 顺序。 Does JavaScript Guarantee Object Property Order?
但是组数组可以节省顺序,因为它们添加了推送功能。
不是。这是不保留顺序的示例:
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()
在这种情况下,人们会期望组顺序为:g2、g3、g1 - 实际情况是它们按 g1、g2、g3 排序。
虽然你可以用原始数组重新排序它们。
const groupedItems = _(data)
.groupBy(item => item.group)
.sortBy(group => data.indexOf(group[0]))
.value()
这将确保项目的原始顺序。