将数组映射到对象kotlin列表

时间:2018-08-09 11:54:03

标签: arrays list kotlin mapping

我想知道将多个数组映射到一个对象列表的方法。

我的意思是我有

val a = arrayOf("A1","A2","A3")
val b = arrayOf("B1","B2","B3")

data class SomeClass(val v1:String, val v2:String)

我想用一种优雅的方式来解析它,以获得这样的列表:

val list = listOf(SomeClass("A1","B1"),SomeClass("A2","B2"),SomeClass("A3","B3"))

我认为它们的长度相同。我想到的唯一方法是:

val list = mutableListOf<SomeClass>() 
for (i in a.indices) 
            array.add(SomeClass(a[i],b[i])

是否有更好,更优雅的解决方案(也许使用Collecions.zip或Array.map)?

3 个答案:

答案 0 :(得分:6)

先尝试Array.zip,然后再尝试map

val list = a.zip(b)
            .map { SomeClass(it.first, it.second) }

或者如果您更喜欢它:

val list = a.zip(b)
            .map { (a, b) -> SomeClass(a, b) }

请注意,如果两个数组的大小均不同,则其他值将被忽略。还要注意,这将创建中间Pair(这是zip的默认转换函数)。尽管我更喜欢显式的map,但有关重载方法的@hotkeys解决方案更合适(您可以保留隐藏的Pair转换):

val list = a.zip(b) { a, b -> SomeClass(a, b) }

当使用引用代替时,重载方法可能发光的地方:

a.zip(b, ::SomeClass)

只要您有一个与压缩参数匹配的构造函数并且对于Pair来说,它是开箱即用的,那将是可行的。

答案 1 :(得分:2)

@Roland's answer上进行了改进,您可以使用zip重载,该重载接受两个参数的函数来立即映射对:

val result = a.zip(b) { x, y -> SomeClass(x, y) }

答案 2 :(得分:0)

您可以像这样编写一些自定义乐趣:

inline fun <T, R, E, V> Iterable<T>.zipThree(other1: Iterable<R>, other2: Iterable<E>, transform: (T, R, E) -> V): List<V> {
        val first = iterator()
        val second = other1.iterator()
        val third = other2.iterator()
        val list = ArrayList<V>()
        while (first.hasNext() && second.hasNext()) {
            list.add(transform(first.next(), second.next(), third.next()))
        }
        return list
    }

并使用此转换获取列表

val strings = listOf("1", "2")
        val ints = listOf(1, 2)
        val boolean = listOf(true, false)

        val listYoutObjects = strings.zipThree(ints, boolean) { one, two, three -> YouObject(one, two, three) }
相关问题