Search code examples
rx-javakotlin

Kotlin - List of items to item of lists


I have a list of objects that I want to convert to an object of lists of following type

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

to an object of the following type:

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

What I'm looking for is something similar to the collect operator in RxJava or a better way of doing this if possible. Any one have ideas?


Solution

  • One simple solution is to use separate map calls to get xs and ys from your Values:

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

    Usage example:

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

    If you want to do it in a single iteration over the Values, you can use 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)
    } 
    

    Since Collection contains read-only lists, I don't see a simpler way to construct it than to make the lists first, of course, not considering expressive yet inefficient functional solutions like this one, which copies xs and ys on each iteration:

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