如何按分组规模从大到小排序对象列表?
如何按分组计数的降序顺序对原始对象列表排序?
我有一个从CSV读取的Person对象列表,示例数据如下:
FirstName, LastName, Age Michael, Moore, 64 John, Doe, 22 John, Brown, 44 Peter, Piper, 46 John, Johnson, 14 Peter, Rabbit, 5
我已经完成了按FirstName分组并统计数量的操作,得到的分组结果是:
FirstName, Count Michael, 1 John, 3 Peter, 2
之后我又按计数降序排序了分组结果,得到:
FirstName, Count John, 3 Peter, 2 Michael, 1
现在我需要按照这个排序后的分组顺序,对原始的Person列表重新排序,最终得到这样的结果:
FirstName, LastName, Age John, Doe, 22 John, Brown, 44 John, Johnson, 14 Peter, Piper, 46 Peter, Rabbit, 5 Michael, Moore, 64
目前我已经实现了以下代码:
val people: List<Person> = readNames(csv) val group = people.groupingBy { it.firstName }.eachCount() val sortedGroups = group.toList().sortedByDescending { (key, value) -> value }
解决方案
你已经完成了最核心的两步——分组计数和排序分组结果,现在只需要利用这个排序后的分组顺序来给原始列表排序就可以了,具体步骤如下:
生成姓名到排序优先级的映射
我们可以把排序后的分组列表转换成一个映射表,让每个FirstName对应一个优先级数字:计数越高的姓名,优先级数字越小(这样排序时会排在更前面)。// 比如John对应0,Peter对应1,Michael对应2 val namePriority = sortedGroups.mapIndexed { index, (name, _) -> name to index }.toMap()按优先级排序原始列表
用上面的映射表作为排序依据,对原始的people列表进行排序:val sortedPeople = people.sortedBy { namePriority[it.firstName] }
把这些步骤整合起来,完整代码如下:
val people: List<Person> = readNames(csv) val group = people.groupingBy { it.firstName }.eachCount() val sortedGroups = group.toList().sortedByDescending { (key, value) -> value } // 生成优先级映射 val namePriority = sortedGroups.mapIndexed { index, (name, _) -> name to index }.toMap() // 按优先级排序原始列表 val sortedPeople = people.sortedBy { namePriority[it.firstName] }
这样得到的sortedPeople就是你想要的结果啦!如果还需要调整每个分组内部的顺序(比如按Age升序/降序排列),可以在sortedBy后面追加thenBy或thenByDescending:
// 分组内按Age升序排列 val sortedPeople = people.sortedBy { namePriority[it.firstName] }.thenBy { it.age }
内容的提问来源于stack exchange,提问作者opticyclic
相关产品推荐
相关产品推荐

