Usar condición para seleccionar la propiedad de sorting en Kotlin

Estoy utilizando sortedBy() para realizar la sorting en la colección de objects.

Como la order puede cambiar dependiendo de la elección del usuario, he terminado con el siguiente código

 val sortedList = if (sortingOrder == WordSortingOrder.BY_ALPHA) { list.sortedBy { it.word.value } } else { list.sortedBy { it.createdAt } } 

Luego realizo más acciones en la colección orderada. Me doy count de que el método sortedBy() espera que se devuelva una propiedad. Me pregunto si hay una manera de integrar la condición de sorting en una cadena de methods de recolección.

Si sus properties son de types diferentes, no podrá seleccionar una de ellas en function de alguna condición como resultado de sortedBy , ya que su sortedBy común se inferiría como Any y no es un subtipo de Comparable<R> como sortedBy espera

En su lugar, puede utilizar sortedWith método, que toma un Comparator , y proporcionar un comparador en function de la condición:

 list.sortedWith( if (sortingOrder == WordSortingOrder.BY_ALPHA) compareBy { it.word.value } else compareBy { it.createdAt } ) 

Aquí se crean comparadores para diferentes properties con la function kotlin.comparisons.compareBy .

A continuación, puede extraer la lógica que selecciona el comparador según el order de sorting de una function:

 list.sortedWith(comparatorFor(sortingOrder)) fun comparatorFor(sortingOrder: WordSortingOrder): Comparator<MyType> = ... 

The sortedBy espera que cualquier function de tipo (T) -> R sea ​​su parámetro. Una propiedad es un caso de esquina de eso.

Lo que significa que puedes hacer esto:

 val sortedList = list .sortedBy { if (sortingOrder == WordSortingOrder.BY_ALPHA) it.word.value else it.createdAt} 

O, si necesita algo más OOP-ish:

 enum class WordSortingOrder(val transform: (MyObject) -> Int) { BY_ALPHA({it.word.value}), BY_ALPHA_REVERSED({-1 * it.word.value}), DEFAULT({it.createdAt}) } val sortedList = list.sortedBy { sortingOrder.transform(it)} 

Puedes hacer algo como:

 list.sortedBy { item -> when(sortingOrder) { WordSortingOrder.BY_ALPHA -> item.word.value else -> item.createdAt } } 

Puede hacer que el argumento lambda pase a sortedBy condicional:

 list.sortedBy(if (sortingOrder == WordSortingOrder.BY_ALPHA) { { it: MyType -> it.word.value } } else { { it: MyType -> it.createdAt } }) 

Puede encontrar el uso de when lugar de if más legible en este escenario:

 list.sortedBy(when (sortingOrder) { WordSortingOrder.BY_ALPHA -> { it: MyType -> it.word.value } else -> { it: MyType -> it.createdAt } }) 

Si sus selectores tienen diferentes types de devolución, puede simplemente ajustar su código existente dentro de list.let { list -> ... } o usar run :

 list.run { if (sortingOrder == WordSortingOrder.BY_ALPHA) { sortedBy { it.word.value } } else { sortedBy { it.createdAt } } } 

A continuación, puede seguir chainging llamadas después de la let / run .

  • Asunto de RxJava: escuche el tipo diferente que el que emite
  • Usando Mockito doAnswer en Kotlin
  • Mantenga BaseActivity en Java compatible con la actividad de Kotlin
  • Kotlin null de Java
  • Declaración de interfaz Java vs Kotlin
  • Necesito una manera de cambiar de forma dinámica y progama el background de un ImageView en una vista de reciclador
  • Varianza genérica del sitio de statement de Koltin <en T> construcción
  • String.intern () devuelve diferentes valores en un controller JDBC
  • Especificación Jpa para encontrar un subset del valor del campo
  • solo se permiten classs en el lado izquierdo de una class literal
  • En Android Studio, ¿cómo cambio las convenciones de nombres de Kotlin?