使用 Kotlin 按多个条件排序

Hoo*_*oni 2 sorting kotlin

我们希望按三个不同的标准对对象进行排序,优先级较高的标准会覆盖下一个):

  1. 状态字段
  2. 时间场
  3. 排序字段
  • status 是枚举并具有自定义排序,我们通过比较器实现。(未知、开放、关闭、)
  • sortBy 字段是一个 Integer,可以相应地排序
  • time 字段可以为 null,我们只想将 null 的排序到顶部,其余的保持原样

例子:

  • 对象1(状态:打开,时间:1,排序:4)
  • Object2(状态:已关闭,时间:空,排序:1)
  • Object3(状态:未知,时间:2,排序:3)
  • Object4(状态:未知,时间:空,排序:2)
  • Object5(状态:打开,时间:1,排序:5)

排序:

  1. 对象 3(状态:未知)
  2. 对象 4(状态:未知,原始列表中的下一项)
  3. 对象 2(状态!=未知,时间:null)
  4. 对象 1(状态!= 未知,时间!= null,排序:4)
  5. 对象 5(状态!= 未知,时间!= null,排序:5)

我们通过以下方式返回列表:

list.sortedWith(statusComparator.thenBy { it.sort }

缺少的是对 time = null 的项目进行排序。如何将 time = null 的项目排序到顶部并保持其余排序不变?

bro*_*oot 5

要根据值是否为 null 进行排序,我们可以...正是这样做,通过检查它是否为 null 进行排序:

list.sortedWith(
    statusComparator
        .thenBy { it.time != null }
        .thenBy { it.sort }
)
Run Code Online (Sandbox Code Playgroud)

它有效,因为false被认为小于true。它返回true任何非空值,因此所有非空值都被认为是相同的。

我们可以加入timesort单步进入一个,如果time为 null,则返回 null,sort否则:

.thenBy { item -> item.time?.let { item.sort } }
// or:
.thenBy { if (it.time == null) null else it.sort }
Run Code Online (Sandbox Code Playgroud)

它的性能可能会更高一些,但我认为这更难理解并且不太灵活。