_.groupBy,但先_.sort

时间:2018-08-08 20:07:47

标签: javascript underscore.js

我得到了这个数组,

我需要对id进行分组,但首先按timestamp进行排序

sample_array = [
    {id: 21, timestamp:1, year: 2012},
    {id: 11, timestamp:2, year: 2017},
    {id: 12, timestamp:3, year: 2016},
    {id: 11, timestamp:4, year: 2014},
    {id: 11, timestamp:5, year: 2015},
    {id: 19, timestamp:6, year: 2016},
    {id: 12, timestamp:7, year: 2016}
    ]

我尝试使用underscore.js实现的目的是先使用时间戳对数组进行排序,然后检查是否存在另一个具有相同ID的条目,然后在下一个ID之前对其进行分组:

预期结果:

[
    {id: 21, timestamp:1, year: 2012},
    {id: 11, timestamp:2, year: 2017},
    {id: 11, timestamp:4, year: 2014},
    {id: 11, timestamp:5, year: 2015},
    {id: 12, timestamp:3, year: 2016},
    {id: 12, timestamp:7, year: 2016},
    {id: 19, timestamp:6, year: 2016}
]

我尝试通过结合使用_.groupBy_.sortBy来实现这一目标。

需要的是:

  1. 按ID分组
  2. 在每个组中按时间戳排序
  3. 按组的最小时间戳(每个组中的第一个时间戳)排序

3 个答案:

答案 0 :(得分:2)

您可以先按timestamp排序,再按id排序,但不要使用数字,因为数字在对象中排在最前面。因此,您需要将数字转换为字符串并按其分组。

然后映射值并展平数组。

var array = [{ id: 21, timestamp:1, year: 2012 }, { id: 11, timestamp:2, year: 2017 }, { id: 12, timestamp:3, year: 2016 }, { id: 11, timestamp:4, year: 2014 }, { id: 11, timestamp:5, year: 2015 }, { id: 13, timestamp:6, year: 2016 }, { id: 12, timestamp:7, year: 2016 }],
    result = _.chain(array)
        .sortBy(['timestamp'])
        .groupBy(o => _ + o.id)
        .map(v => v)
        .flatten()
        .value();

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

答案 1 :(得分:1)

根据下一次了解:

  

按ID分组,按每个组中的时间戳排序,然后按最小时间戳(实际上是每个组中的第一个时间戳)对组进行排序,然后将组展平到统一列表中。

_.chain(sample_array)
 .groupBy('id')
 .mapObject(groupPerId=> _.sortBy(groupPerId, 'timestamp'))
 .sortBy(groupPerId=> groupPerId[0].timestamp)
 .flatten()
 .value()

答案 2 :(得分:0)

如果此数组有问题,可以简单地解决以下问题,如果在时间戳上加零,则可以用数字玩,每个时间戳取一个确切的数字:),检查它是否可以工作(此示例最多为5位)时间戳记)(如果有更多时间戳记,则可以在开头添加零

    sample_array.sort(function(a,b){
return Number(a.id.toString()+('00000'+a.timestamp.toString()).substr(a.timestamp.toString().length-1))-Number(b.id.toString()+('00000'+b.timestamp.toString()).substr(b.timestamp.toString().length-1))
})