首页 > 解决方案 > lodash groupBy 正在更改我收藏中的顺序

问题描述

我有一个数组:

  { 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 开头吗?

我应该怎么做才能保持我的收藏顺序?

标签: javascriptlodashtraversal

解决方案


这就是EcmaScript 1中属性的排序方式:当属性名称是数组索引值的规范字符串表示形式(即十进制数字,最多 2 32 -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对象属性的“顺序”有很多细微差别。请参阅ES6 是否为对象属性引入了明确定义的枚举顺序?更详细的解释


推荐阅读