歌林 – 项目清单项目列表

我有一个对象的列表,我想要转换为以下类型的列表对象

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

到以下类型的对象:

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

我正在寻找的东西类似于RxJava中的collect运算符,或者如果可能的话,这是一个更好的方法。 任何人有想法?

一个简单的解决方案是使用单独的map调用来从您的Value获取xsys

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

用法示例:

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

如果你想通过Value来进行一次迭代,你可以使用简单的for循环:

 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) } 

因为Collection包含只读列表,所以我没有看到比列表首先更简单的方法,当然,不考虑像这样的表达式但低效的功能性解决方案,它在每次迭代中复制xsys

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

相当于一个收藏家将是一个折叠

 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]) 

但是对于这个特殊情况来说,简单地映射每个位置就可以了。

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

我运行了@ hotkey的答案提供的所有方法,地图方法是最快的。 以下是我跑的代码:

 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)) 

示例输出是:

 Fold takes: 12776 Map takes: 12 Collection takes: 29