lodash groupBy 正在更改我的 collection 中的顺序
lodash groupBy is changing order in my collection
我有一个数组:
{ date: '25', value: '1410' },
{ date: '25', value: '1132' },
{ date: '26', value: '1482' },
{ date: '26', value: '3546' },
{ date: '27', value: '3748' },
{ date: '27', value: '3482' },
{ date: '28', value: '3164' },
{ date: '28', value: '2626' },
{ date: '29', value: '1110' },
{ date: '29', value: '948' },
{ date: '01', value: '1260' },
{ date: '01', value: '1228' },
{ date: '02', value: '1120' },
{ date: '02', value: '1056' },
{ date: '03', value: '1214' },
{ date: '04', value: '1100' },
{ date: '05', value: '1624' },
{ date: '06', value: '1544' },
{ date: '07', value: '1846' },
{ date: '08', value: '1370' },
{ date: '09', value: '1262' },
{ date: '10', value: '542' },
{ date: '10', value: '492' },
当我这样做时:
let groups = _.groupBy(conso, 'date');
我得到的结果是分组的,但是我失去了顺序,第一个元素不是 25,而是 10:
{
'10': [
{ date: '10', value: '542' },
{ date: '10', value: '492' },
....
]
}
这是想要的行为吗?如果按字母顺序排序,它不应该从 01 开始吗?
我应该如何保持我的 collection 的顺序?
这就是属性 ordered in EcmaScript1:当 属性 名称是 数组索引的规范字符串表示时 值(即,十进制数字,最多 232-1,并且没有填充零),然后这些在任何其他属性之前按数字顺序排序。
请注意,这与 lodash 无关,而是与 EcmaScript 本身有关。
要强制执行命令,您不应将结果设为普通对象,而应设为成对的数组,其中成对中的第一个值是(数字)属性,第二个是实际值(在你的例子中是对象数组)。
在纯 JS 中,您可以创建基于对的结构:
let map = new Map(conso.map(o => [o.date, []]));
conso.forEach(o => map.get(o.date).push(o));
let result = [...map];
如果你真的需要普通对象格式,那么你可以考虑在属性前加上一些非数字字符。
1对象属性的 "order" 有很多细微差别。请参阅 以获得更详尽的解释
js中的对象没有排序,这意味着在向对象添加元素(键+值)后,它的位置将由其键上的随机函数定义(它从一个prog-lang变为另一个)
其他可能的解决方案是使用数组数组。其中主数组将代表整个组,每个子数组将代表一个特定的组。
我们可以通过在当前结果之上进行简单排序来实现它。
var conso = [{ date: '25', value: '1410' },
{ date: '25', value: '1132' },
{ date: '26', value: '1482' },
{ date: '26', value: '3546' },
{ date: '27', value: '3748' },
{ date: '27', value: '3482' },
{ date: '28', value: '3164' },
{ date: '28', value: '2626' },
{ date: '29', value: '1110' },
{ date: '29', value: '948' },
{ date: '01', value: '1260' },
{ date: '01', value: '1228' },
{ date: '02', value: '1120' },
{ date: '02', value: '1056' },
{ date: '03', value: '1214' },
{ date: '04', value: '1100' },
{ date: '05', value: '1624' },
{ date: '06', value: '1544' },
{ date: '07', value: '1846' },
{ date: '08', value: '1370' },
{ date: '09', value: '1262' },
{ date: '10', value: '542' },
{ date: '10', value: '492' },];
let groups = _.groupBy(conso, 'date');
/// create an array of the original sorting dates
let sorting = _.map(conso, 'date')
// sort the group values (arrays) by their first element's date
// compare its value to the original solution date.
let finalSolution = _.sortBy(
Object.values(groups),
(k) => sorting.indexOf(k[0].date)
)
你可以阅读更多关于js对象键排序的内容here
我有一个数组:
{ date: '25', value: '1410' },
{ date: '25', value: '1132' },
{ date: '26', value: '1482' },
{ date: '26', value: '3546' },
{ date: '27', value: '3748' },
{ date: '27', value: '3482' },
{ date: '28', value: '3164' },
{ date: '28', value: '2626' },
{ date: '29', value: '1110' },
{ date: '29', value: '948' },
{ date: '01', value: '1260' },
{ date: '01', value: '1228' },
{ date: '02', value: '1120' },
{ date: '02', value: '1056' },
{ date: '03', value: '1214' },
{ date: '04', value: '1100' },
{ date: '05', value: '1624' },
{ date: '06', value: '1544' },
{ date: '07', value: '1846' },
{ date: '08', value: '1370' },
{ date: '09', value: '1262' },
{ date: '10', value: '542' },
{ date: '10', value: '492' },
当我这样做时:
let groups = _.groupBy(conso, 'date');
我得到的结果是分组的,但是我失去了顺序,第一个元素不是 25,而是 10:
{
'10': [
{ date: '10', value: '542' },
{ date: '10', value: '492' },
....
]
}
这是想要的行为吗?如果按字母顺序排序,它不应该从 01 开始吗?
我应该如何保持我的 collection 的顺序?
这就是属性 ordered in EcmaScript1:当 属性 名称是 数组索引的规范字符串表示时 值(即,十进制数字,最多 232-1,并且没有填充零),然后这些在任何其他属性之前按数字顺序排序。
请注意,这与 lodash 无关,而是与 EcmaScript 本身有关。
要强制执行命令,您不应将结果设为普通对象,而应设为成对的数组,其中成对中的第一个值是(数字)属性,第二个是实际值(在你的例子中是对象数组)。
在纯 JS 中,您可以创建基于对的结构:
let map = new Map(conso.map(o => [o.date, []]));
conso.forEach(o => map.get(o.date).push(o));
let result = [...map];
如果你真的需要普通对象格式,那么你可以考虑在属性前加上一些非数字字符。
1对象属性的 "order" 有很多细微差别。请参阅
js中的对象没有排序,这意味着在向对象添加元素(键+值)后,它的位置将由其键上的随机函数定义(它从一个prog-lang变为另一个)
其他可能的解决方案是使用数组数组。其中主数组将代表整个组,每个子数组将代表一个特定的组。
我们可以通过在当前结果之上进行简单排序来实现它。
var conso = [{ date: '25', value: '1410' },
{ date: '25', value: '1132' },
{ date: '26', value: '1482' },
{ date: '26', value: '3546' },
{ date: '27', value: '3748' },
{ date: '27', value: '3482' },
{ date: '28', value: '3164' },
{ date: '28', value: '2626' },
{ date: '29', value: '1110' },
{ date: '29', value: '948' },
{ date: '01', value: '1260' },
{ date: '01', value: '1228' },
{ date: '02', value: '1120' },
{ date: '02', value: '1056' },
{ date: '03', value: '1214' },
{ date: '04', value: '1100' },
{ date: '05', value: '1624' },
{ date: '06', value: '1544' },
{ date: '07', value: '1846' },
{ date: '08', value: '1370' },
{ date: '09', value: '1262' },
{ date: '10', value: '542' },
{ date: '10', value: '492' },];
let groups = _.groupBy(conso, 'date');
/// create an array of the original sorting dates
let sorting = _.map(conso, 'date')
// sort the group values (arrays) by their first element's date
// compare its value to the original solution date.
let finalSolution = _.sortBy(
Object.values(groups),
(k) => sorting.indexOf(k[0].date)
)
你可以阅读更多关于js对象键排序的内容here