我有以下列表:
[-1, -1, 2, 3, 4, 5, -1, 9, 10, 11, -1, -1, 23, 24, 25]
我想要的是以下列表:
[Pair(2,5), Pair(9,11), Pair(23,25)]
我可以使用start
和end
等临时变量进行迭代。但我正在寻找List
上的转化方法,例如map
,filter
等,以获得我的解决方案。
答案 0 :(得分:1)
首先,我将定义一个操作,将原始元素拆分为不包括-1
的数字的连续子范围。这可以通过Sequence<T>
以上的操作方便地完成,例如takeWhile
和dropWhile
。唯一棘手的部分是创建一个迭代器并将其用于重新排列范围的每个项目:
fun <T> Sequence<T>.split(separator: T): Sequence<List<T>> {
val originalIterator by lazy { iterator() }
val eachSequence = Sequence { originalIterator }
.dropWhile { it == separator }
.takeWhile { it != separator }
return generateSequence { eachSequence.toList().takeIf { it.isNotEmpty() } }
}
便捷功能,可以轻松地将split
应用于List
:
fun <T> List<T>.split(separator: T) =
asSequence().split(separator).toList()
然后只取每个结果范围的第一个和最后一个项目:
fun <T> List<T>.splitToRanges(separator: T) =
split(separator).map { it.first() to it.last() }
示例:
val ints = listOf(-1, -1, 2, 3, 4, 5, -1, 9, 10, 11, -1, -1, 23, 24, 25)
println(ints.splitToRanges(-1)) // [(2, 5), (9, 11), (23, 25)]
完成可运行的示例:(link)