如何使用 Kotlin 谓词将列表拆分为子列表?

2023-12-10

我正在尝试一种惯用且理想的功能方式来将 Kotlin 中的列表拆分为子列表。

想象一下输入是["aaa", "bbb", "", "ccc", "", "ddd", "eee", "fff"],我想回来[["aaa", "bbb"], ["ccc"], ["ddd", "eee", "fff"]]对于给定的谓词string.isEmpty().

使用 for 循环和累加器非常简单;但我还没有找到一种我认为足够可读的功能性编写方法。

到目前为止我最好的结果是:

lines.foldIndexed(Pair(listOf<List<String>>(), listOf<String>()), { idx, acc, line ->
    when {
    idx + 1 == lines.size -> {
        Pair(acc.first + listOf(acc.second + line), listOf())
    }
    line.isEmpty() -> {
        Pair(acc.first + listOf(acc.second), listOf())
    }
    else -> {
        Pair(acc.first, acc.second + line)
        }
    }
}).first

本质上,我正在使用fold使用双累加器来跟踪当前列表并在找到谓词时重置。该列表将输入到此时的完整结果中。我正在使用一个折叠索引为了得到我的最后一个清单。

大家知道有什么更好的办法吗?

作为参考,循环版本可以是

val data = mutableListOf<String>()
var currentData = ""
for(line in lines){
    if(line.isEmpty()) {
        data.add(currentData)
        currentData = ""
    }
    else{
        currentData = "$currentData $line"
    }
}
data.add(currentData)

Thanks !


我建议首先找到分割点(手动添加边缘索引),然后进行切片:

val lines = listOf("aaa", "bbb", "", "ccc", "", "ddd", "eee", "fff")
val result = lines
    .flatMapIndexed { index, x ->
        when {
            index == 0 || index == lines.lastIndex -> listOf(index)
            x.isEmpty() -> listOf(index - 1, index + 1)
            else -> emptyList()
        }
    }
    .windowed(size = 2, step = 2) { (from, to) -> lines.slice(from..to) }
println(result) //[[aaa, bbb], [ccc], [ddd, eee, fff]]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Kotlin 谓词将列表拆分为子列表? 的相关文章

随机推荐