Kotlin stlib 中是否有用于将 List<Pair<A, B>>转换为 Pair<List<A>, List<B 的函数>>

Is there a function in the Kotlin stlib for transforming a List<Pair<A, B>> into a Pair<List<A>, List<B>>

提问人:greyhairredbear 提问时间:10/19/2023 最后编辑:greyhairredbear 更新时间:10/21/2023 访问量:84

问:

我目前拥有与以下内容类似的机制的代码

fun main() {
    val listOfLists = listOf(listOf("1234", "1", "42"), listOf("hello", "there"))
    
    val (lengths: List<List<Int>>, resultingListsOfLists: List<List<String>?>) =
        listOfLists
            .map {
                val lengths = it.map { it.count() }
                Pair(
                    lengths,
                    if (lengths.sum() > 5) {
                        // doing some transformation here in my original code,
                        // but for the sake of keeping it simple, just return `it`
                        it 
                    } else {
                        null
                    }
                )
            }
            .let { mapped ->
                println(mapped)
                Pair(mapped.map { it.first }, mapped.map { it.second })
            }
            
    println(lengths)
    println(resultingListsOfLists)
}

哪个应该输出

[([4, 1, 2], [1234, 1, 42]), ([5, 5], [hello, there])]
[[4, 1, 2], [5, 5]]
[[1234, 1, 42], [hello, there]]

它对我的用例来说已经足够了。

但是,最后一部分有点冗长。了解了 Kotlin,我觉得应该有一种方法可以使转换变得更加简洁和可读。letList<Pair<A, B>>Pair<List<A>, List<B>>

stdlib 中是否有实现此目的的功能?

我知道 ,但这不允许解构生成的 Pair,并且可能存在重复键的问题。associate

Kotlin 转换 习语

评论

4赞 Sweeper 10/20/2023
接近的投票是基于意见的。我不同意它,因为对 Kotlin 中的“惯用语”几乎达成了共识,尤其是在这种情况下,您在标题中描述的内容正是这样做的。也许编辑掉可以被认为是基于意见的短语。unzip

答:

5赞 Sweeper 10/19/2023 #1

您正在寻找 unzip - 一种转换为 .您可以将最终调用替换为 。List<Pair<T, U>>Pair<List<T>, List<U>>letunzip

如果你将你所做的“转换”提取到另一个函数中,你可以写一些非常可读的东西,比如 .it.takeIf { ... }?.run(::process)

listOfLists
    .map {
        val lengths = it.map(String::length)
        lengths to (it.takeIf { lengths.sum() > 5 }?.run(::process))
    }.unzip()