Kotlin stlib 中是否有一个函数可以将 List<Pair<A, B>> 转换为 Pair<List<A>,List<B>>

问题描述 投票:0回答:1

我目前的代码与以下机制类似

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,我觉得应该有一种方法可以使其更加优雅和可读,也许可以借助 stdlib 中的函数。

stdlib中有函数可以实现这个功能吗?

我知道

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

kotlin transformation idioms
1个回答
4
投票

您正在寻找

unzip
- 一种将
List<Pair<T, U>>
转换为
Pair<List<T>, List<U>>
的方法。您可以将最后的
let
调用替换为
unzip

如果您将所做的“转换”提取到另一个函数中,您可以编写一些非常可读的内容,例如

it.takeIf { ... }?.run(::process)

listOfLists
    .map {
        val lengths = it.map(String::length)
        lengths to (it.takeIf { lengths.sum() > 5 }?.run(::process))
    }.unzip()
© www.soinside.com 2019 - 2024. All rights reserved.