Как отсортировать коллекцию по нескольким значениям И нулям в конце, используя доступные удобные методы Kotlin - PullRequest
1 голос
/ 05 марта 2020

Ранее я использовал методы sortedWith и compareBy , и он способен сортировать по нескольким параметрам.

Я также использовал nullsLast метод раньше, и он довольно удобен, как и другие два.

Однако с этими методами я не могу найти способ сортировки коллекции с помощью следующих правил сортировки:

С учетом класса:

data class MyClass(
    val varA: String?,
    val varB: String
)
  • сортировка в соответствии с varA по алфавиту и нулями / пробелами, чтобы быть последними; затем

  • сортировка по varB по алфавиту

Итак, допустим, у меня есть следующая коллекция:

val collection = listOf(
    MyClass(null, "A"),
    MyClass("a", "B"),
    MyClass("c", "C"),
    MyClass("b", "D"),
    MyClass("", "E"),
    MyClass("a", "F"),
    MyClass("b", "G"),
    MyClass(null, "H"),
    MyClass("", "I")
)

затем он должен быть отсортирован по:

    MyClass("a", "B")
    MyClass("a", "F")
    MyClass("b", "D")
    MyClass("b", "G")
    MyClass("c", "C")
    MyClass(null, "A")
    MyClass("", "E")
    MyClass(null, "H")
    MyClass("", "I")

есть ли однострочный код, который я могу использовать так же, как compareBy , который использует параметр vararg

Ответы [ 2 ]

2 голосов
/ 05 марта 2020

Я бы сделал это так (см. kotlin.comparisons документация ):

val comparator = compareBy<String, MyClass>(nullsLast(), { it.varA.let { if (it == "") null else it } }).thenBy { it.varB }

collection.sortedWith(comparator)
1 голос
/ 05 марта 2020

Конечно, для этого есть однострочный:

collection.sortedBy {if(it.varA != null && it.varA.isNotEmpty()) it.varA + it.varB else "z" + it.varB}

Затем напечатайте его:

output.forEach { println("Myclass(${it.varA}, ${it.varB})") }

Вывод:

Myclass(a, B)
Myclass(a, F)
Myclass(b, D)
Myclass(b, G)
Myclass(c, C)
Myclass(null, A)
Myclass(, E)
Myclass(null, H)
Myclass(, I)

Пояснение:

Нам нужно разделить случаи, когда мы сортируем по varA, а когда по varB здесь. Вот почему существует условие if(it.varA != null && it.varA.isNotEmpty()), которое говорит, что мы будем сортировать по varA, только если его значение не равно null или "".

В противном случае мы сортируем по строке "z" + it.varB, что означает, что мы сортируем по varB, , но с префиксом z, что гарантирует, что эти элементы будут в конце отсортированной коллекции.

Чтобы легче понять как это работает, вы можете попробовать следующий код:

    val output = collection.map { if(it.varA != null && it.varA.isNotEmpty()) it.varA + it.varB else "z" + it.varB }

    output.sortedBy { it }.forEach { println(it) }

Этот выводит следующие строки:

aB
aF
bD
bG
cC
zA
zE
zH
zI

Теперь это должно быть более очевидно. : -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...