【问题标题】:Kotlin sort array by value in rangeKotlin 按范围内的值对数组进行排序
【发布时间】:2018-02-04 19:51:09
【问题描述】:

让我们有一个class Player(val position: Int, val time: Float),我们想通过positionplayers 的数组或列表进行排序。如果其中一些players 在第一次排序后具有相同的position,我们希望将它们按time 分组。我所说的组是指一组具有相同位置的players

我知道

list.sortedWith(compareBy<Foo> { it.a }.thenByDescending { it.b }.thenBy { it.c })

但当然它并不能解决这个问题。

在 Kotlin 中有什么聪明的方法来完成这个简单的任务吗?我们可以通过检查位置和交换项目来手动排序,但我想知道 Kotlin 在这种情况下是否有话要说。

【问题讨论】:

  • 为什么sortedWith不解决这个案子?
  • 你应该让你的问题更清楚:你有什么样的数据结构,你想让这个总是排序,即每当添加一个新元素时,它应该在适当的位置排序位置还是您想要一个按需排序的功能?那你需要什么数据结构呢?
  • 是的,我没有具体说明这一点。我希望 kotlin 用这样的案例来炫耀,将数组转换为映射然后再转换回数组只是不想要的解决方案。我想到了一些技巧,比如并行排序,甚至使用一些额外的谓词,但你是对的,我们可以通过将列表转换为映射然后再返回来对其进行排序。我将您的答案标记为正确。

标签: android algorithm sorting kotlin comparable


【解决方案1】:

您可以先按 positiontime 排序,然后使用标准 Kotlin 功能按 time 分组。

示例

data class Player(val position: Int, val time: Float)

val p1 = Player(1, 10f)
val plys = arrayOf(p1, p1.copy(position = 3),
        p1.copy(time = 0f), p1.copy(time = 20f),
        p1.copy(position = 2), p1.copy(position = 2, time = 20f))

val groupBy = plys.sortedWith(compareBy(Player::position, Player::time))
                  .groupBy { it.position }

说明

  1. Array 排序为PlayerpositiontimesortedWith + compareBy
  2. Playerposition 分组

结果

结果是Map<Int,List<Player>,在示例中如下所示:

    {
     1=[Player(position=1, time=0.0), Player(position=1, time=10.0), Player(position=1, time=20.0)], 
     2=[Player(position=2, time=10.0), Player(position=2, time=20.0)],
     3=[Player(position=3, time=10.0)]
    }

【讨论】:

  • 感谢您的回答。我知道groupBy{},但它会生成地图而不是您自己编写的列表。它改变了保持players 的结构,在我的情况下,它是一个交易破坏者。
  • 使用toList() 可以轻松地将地图转换为列表...这应该被标记为正确答案,或者OP应该澄清所需的结果
  • 嗯,不希望通过将数组转换为映射然后返回数组来对数组进行排序,但我对此并不具体,所以我将此答案标记为正确
猜你喜欢
  • 2017-10-30
  • 2019-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-01
  • 1970-01-01
  • 2021-08-21
  • 1970-01-01
相关资源
最近更新 更多