歌林 – 项目清单项目列表
我有一个对象的列表,我想要转换为以下类型的列表对象
data class Value(val x : Int, val y: Int)
到以下类型的对象:
data class Collection(val xs : List<Int>, val ys: List<Int>)
我正在寻找的东西类似于RxJava中的collect
运算符,或者如果可能的话,这是一个更好的方法。 任何人有想法?
一个简单的解决方案是使用单独的map
调用来从您的Value
获取xs
和ys
:
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
包含只读列表,所以我没有看到比列表首先更简单的方法,当然,不考虑像这样的表达式但低效的功能性解决方案,它在每次迭代中复制xs
和ys
:
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