我有一个需要压缩到int范围列表的整数列表,而不会丢失任何信息(必须有一种方法可以反转此操作)。
目前我有:
val ints = listOf(8, 9, 45, 48, 49, 60, 61, 61, 62, 63, 3, 4, 5, 4, 5, 6)
val out = ints
.map { it..it }
.fold(mutableListOf(ints[0]..(ints[0] - 1)),
{ acc, next ->
val prev = acc.last()
if (prev.last + 1 == next.first) {
acc[acc.lastIndex] = prev.first..next.last
} else {
acc.add(next)
}
acc
}).toList()
正确地产生:
[8..9, 45..45, 48..49, 60..61, 61..63, 3..5, 4..6]
我的解决方案中有两个方面我不喜欢,
由于fold的初始值
kotlin非常详细。我觉得这可以通过更好的方式解决。
那么,问题是如何修复1和/或2?
提前致谢!
答案 0 :(得分:2)
由于您实际变异acc
并在fold
的所有迭代中返回相同的范围列表,因此您可能不需要fold
,即forEach
就够了。
然后,将每个数字映射到it..it
似乎在这里是多余的。
考虑到上述两个注释,可以得到以下解决方案的简化版本:
val result = mutableListOf<IntRange>()
ints.forEach {
val lastRange = result.lastOrNull()
if (lastRange?.endInclusive == it - 1)
result[result.lastIndex] = lastRange.first..it
else
result += it..it
}
答案 1 :(得分:1)
我的解决方案看起来没什么不同,但我能够解决您的空列表问题:
val out = ints.fold(mutableListOf<IntRange>()) { acc, next ->
acc.apply {
if(isNotEmpty() && last().endInclusive.inc() == next) {
this[lastIndex] = this[lastIndex].start .. next
} else {
add(next..next)
}
}
}
它的映射也有点少,使用apply会消除一些冗长,最后不得不引用acc
。