【问题标题】:Mapping arrays to list of objects kotlin将数组映射到对象列表 kotlin
【发布时间】:2019-01-16 21:06:53
【问题描述】:

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

我的意思是例如我有

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

【问题讨论】:

  • 我会同时选择zipmap...请注意,您的变体有缺陷.. 如果a 中有更多元素,您会得到ArrayIndexOutOfBoundException

标签: arrays list kotlin mapping


【解决方案1】:

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

请注意,如果两个数组的大小不同,则忽略附加值。另请注意,这将创建中间Pairs(这是zip 的默认转换函数)。尽管我更喜欢显式的map,但关于重载方法的@hotkeys 解决方案更合适(你省去隐藏的Pair-transformation):

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

重载方法的亮点可能在于使用引用代替:

a.zip(b, ::SomeClass)

只要您有一个与压缩参数匹配的构造函数,并且对于Pair(还没有?),这将起作用。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 如果我有数组 a,b,c 并且想要做类似的事情怎么办val result = a.zip(b,c) { x,y,z -&gt; SomeClass(x,y,z)}
    • 您可以执行a.zip(b).zip(c) { ab, c -&gt; SomeClass(ab.first, ab.second, c) } 之类的操作,但正如您所见,这并不好。您可能应该提供自己的映射/压缩功能...
    【解决方案3】:

    你可以像这样写一些自定义的乐趣:

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

    【讨论】:

    • 一定要在while-条件中检查third.hasNext()。请注意,在这个问题中并没有真正问到您在这里所做的事情,但是有一个,您的答案是否适合:stackoverflow.com/q/50078266/6202869
    猜你喜欢
    • 1970-01-01
    • 2021-05-18
    • 1970-01-01
    • 2021-09-22
    • 1970-01-01
    • 2022-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多