Collections 将int列表折叠到kotlin中的范围列表
我有一个整数列表,需要在不丢失任何信息的情况下压缩为整数范围列表(必须有一种方法来反转此操作) 目前我有:Collections 将int列表折叠到kotlin中的范围列表,collections,functional-programming,kotlin,Collections,Functional Programming,Kotlin,我有一个整数列表,需要在不丢失任何信息的情况下压缩为整数范围列表(必须有一种方法来反转此操作) 目前我有: 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 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]
但我的解决方案中有两个方面我不喜欢
提前谢谢 我的解决方案看起来没什么不同,但我能够解决您的空列表问题:
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)
}
}
}
val out=ints.fold(mutableListOf()){acc,next->
根据申请{
if(isNotEmpty()&&last().endInclusive.inc()==next){
此[lastIndex]=此[lastIndex]。开始..下一步
}否则{
添加(下一个..下一个)
}
}
}
它的映射也少了一点,使用apply可以去掉一些冗长的内容,并且在最后必须引用
acc
。因为你实际上改变了acc
,并在折叠的所有迭代中返回相同的范围列表,所以你可能并不真正需要折叠,也就是说,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
}
val result=mutableListOf()
弗雷赫国际酒店{
val lastRange=result.lastOrNull()
if(lastRange?.endInclusive==it-1)
result[result.lastIndex]=lastRange.first..it
其他的
结果+=它..它
}
我喜欢它的简化和单一的表达。顺便说一句,与原始命令式循环相比,在循环中使用lambda如何/如果会影响性能?因为apply
是一个,它在循环中的使用不会影响性能。我喜欢您的解决方案。感谢@hotkey提供的宝贵提示。我很难找到答案来接受。选择Todd's作为单一表达式。我知道你的也可以通过apply
进行转换。没问题。虽然我个人认为增加另一个嵌套级别并使接收者隐式地使用apply
可能会降低可读性,但这是基于观点的判断。