如何从对象列表中按字段ts
分组并以最大startDate
分组来获取新列表?
def list = [
new Timeserie(ts:11, startDate:new Date().parse('yyyy-MM-dd HH:mm:ss', '2018-02-12 20:04:36')),
new Timeserie(ts:11, startDate:new Date().parse('yyyy-MM-dd HH:mm:ss', '2018-02-12 20:14:36')),
new Timeserie(ts:12, startDate:new Date().parse('yyyy-MM-dd HH:mm:ss', '2018-02-12 20:24:36')),
new Timeserie(ts:12, startDate:new Date().parse('yyyy-MM-dd HH:mm:ss', '2018-02-12 20:34:36')),
]
list.each{ println it }
def byTs = list.groupBy({ tss -> tss.ts })
println "byTs Size: " + byTs.size()
预期结果:
[new Timeserie(ts:11, startDate:new Date().parse('yyyy-MM-dd HH:mm:ss', '2018-02-12 20:14:36'),
new Timeserie(ts:12, startDate:new Date().parse('yyyy-MM-dd HH:mm:ss', '2018-02-12 20:34:36'))]
答案 0 :(得分:0)
您可以通过链接进行3项操作来获得预期的结果:
groupBy { it.ts }
创建一个映射,其中键为ts
,值为时间序列列表Map<Integer, List<Timeserie>>
collectEntries { [(it.key): it.value.max { it.startDate }] }
将Map<Integer, List<Timeserie>>
转换为Map<Integer, Timeserie>
,其中映射对象是最高startDate
的时间序列values()
从Collection<Timeserie>
获得Map<Integer, Timeserie>
完整的示例如下:
def list = [
new Timeserie(ts:11, startDate:new Date().parse('yyyy-MM-dd HH:mm:ss', '2018-02-12 20:04:36')),
new Timeserie(ts:11, startDate:new Date().parse('yyyy-MM-dd HH:mm:ss', '2018-02-12 20:14:36')),
new Timeserie(ts:12, startDate:new Date().parse('yyyy-MM-dd HH:mm:ss', '2018-02-12 20:24:36')),
new Timeserie(ts:12, startDate:new Date().parse('yyyy-MM-dd HH:mm:ss', '2018-02-12 20:34:36')),
]
def result = list.groupBy { it.ts }
.collectEntries { [(it.key): it.value.max { it.startDate }] }
.values()
println result
输出:
[Timeserie(11, Mon Feb 12 20:14:36 CET 2018), Timeserie(12, Mon Feb 12 20:34:36 CET 2018)]
答案 1 :(得分:0)
我会用withDefault()
来解决问题:
def list = [ [ts:11, startDate:new Date().parse('yyyy-MM-dd HH:mm:ss', '2018-02-12 20:04:36')], [ts:11, startDate:new Date().parse('yyyy-MM-dd HH:mm:ss', '2018-02-12 20:14:36')], [ts:12, startDate:new Date().parse('yyyy-MM-dd HH:mm:ss', '2018-02-12 20:24:36')], [ts:12, startDate:new Date().parse('yyyy-MM-dd HH:mm:ss', '2018-02-12 20:34:36')], ]
def res = list.inject( [:].withDefault{ [ ts:null, startDate:new Date( 0 ) ] } ){ res, ts ->
res[ ts.ts ].ts = ts.ts
res[ ts.ts ].startDate = new Date( Math.max( ts.startDate.time, res[ ts.ts ].startDate.time ) )
res
}.values()
assert '[[ts:11, startDate:Mon Feb 12 20:14:36 UTC 2018], [ts:12, startDate:Mon Feb 12 20:34:36 UTC 2018]]' == res.toString()
注意:为简单起见,我将Timeserie
类替换为Map