Kolin – Lista de artículos para el artículo de lists

Tengo una list de objects que quiero convertir a un object de lists del siguiente tipo

data class Value(val x : Int, val y: Int) 

a un object del siguiente tipo:

 data class Collection(val xs : List<Int>, val ys: List<Int>) 

Lo que estoy buscando es algo similar al operador de collect en RxJava o una mejor manera de hacerlo si es posible. ¿Alguien tiene ideas?

Una solución simple es usar llamadas de map separadas para get xs y ys de su Value s:

 fun collectionOf(values: List<Value>) = Collection(values.map { it.x }, values.map { it.y }) 

Ejemplo de uso:

 val values = listOf(Value(1, 2), Value(3, 4)) val collection = collectionOf(values) // Collection(xs=[1, 3], ys=[2, 4]) 

Si desea hacerlo en una única iteración sobre Value s, puede usar simple for loop:

 fun collectionOf(values: List<Value>) { val xs = mutableListOf<Int>() val ys = mutableListOf<Int>() for ((x, y) in values) { xs.add(x) ys.add(y) } return Collection(xs, ys) } 

Dado que Collection contiene lists de solo lectura, no veo una forma más sencilla de buildlo que hacer primero las lists, por supuesto, sin considerar soluciones funcionales expresivas pero ineficientes como esta, que copy xs e ys en cada iteración:

 fun collectionOf(values: List<Value>) = values.fold(Collection(listOf(), listOf())) { acc, it -> Collection(acc.xs + it.x, acc.ys + it.y) } 

El equivalente de un coleccionista sería un doblez

 val values = listOf(Value(1,2), Value(3,4), Value(5,6)) val collection = values.fold(Collection(listOf(), listOf())) { acum, value -> Collection(acum.xs + value.x, acum.ys + value.y)} println(collection) // => Collection(xs=[1, 3, 5], ys=[2, 4, 6]) 

Pero para este caso en particular, es más simple mapear cada position del touple.

 val collection2 = Collection(values.map(Value::x), values.map(Value::y)) println(collection2) // => Collection(xs=[1, 3, 5], ys=[2, 4, 6]) 

Ejecuté todos los methods provistos en la respuesta de @keykey y el método de map es el más rápido. A continuación está el código que ejecuté:

 data class Value(val x : Int, val y: Int) data class Collection(val xs : List<Int>, val ys: List<Int>) fun collectionOf(values: List<Value>): Collection { val xs = mutableListOf<Int>() val ys = mutableListOf<Int>() for ((x, y) in values) { xs.add(x) ys.add(y) } return Collection(xs, ys) } var startTime = System.currentTimeMillis() (1..100000).map { Value(it * 1, it * 3) }.fold(Collection(listOf(), listOf()), { acc, value -> Collection(acc.xs + value.x, acc.ys + value.y) }) println("Fold takes: " + (System.currentTimeMillis() - startTime)) startTime = System.currentTimeMillis() (1..100000).map { Value(it * 1, it * 3) }.let { Collection(it.map { it.x }, it.map { it.y }) } println("\nMap takes: " + (System.currentTimeMillis() - startTime)) startTime = System.currentTimeMillis() collectionOf((1..100000).map { Value(it * 1, it * 3) }) println("\nCollection takes: " + (System.currentTimeMillis() - startTime)) 

La salida de muestra es:

 Fold takes: 12776 Map takes: 12 Collection takes: 29 
  • Rx Java Retrofit con flatMap se ejecuta solo una vez
  • Para una function de Kotlin utilizada como expresión, ¿hay una forma concisa de operar y devolver un valor?
  • RxJava2 observable no procesando en Siguiente cuando hay un cambio
  • RxJava BehaviorSubject no emite el último elemento?
  • Ventana cornetworkingera RxJava
  • Comportamiento de RxJava Schedulers.immediate () mientras testings unitarias
  • Llamada asincrónica para cada elemento dentro de una colección
  • Kotlin: Cómo convertir la testing que usa Thread.sleep a RxJava TestScheduler
  • Cómo notificar a Observable cuando finalice CountdownTimer
  • Obtener files adjuntos de publicaciones de Facebook devolver NullPointerException
  • ¿Debo cancelar la suscripción cuando uso rxbinding?