前言
你是否对当前循环体和外部循环,理解不到位,截取不到你想要的字符串?举个栗子:比如我需要对一个字符串earTag = ["9840000005096366"],进行各种操作,实现取出newEarTag = 5096366 。
其中,对0000005096366,这串数字进行取值的时候,在找解决方法的时候我发现Java中的很多countinue和break的操作来跳出循环的方式,无法照搬到Kotlin中实现类似功能。
发现问题
为什么需要跳出循环呢?0000005096366这串字符请问如何截取到5096366,也就是说除去前面的零,从第一个非零字符取到末尾。在遍历的时候Kotlin需要用遍历的方式去遍历每一个char,即:'0' 。但如何在遍历到非零的char时,跳出整个forEach循环呢?
于是我搬出了度娘,百度一下你就知道!结果当然不一而足。但我发现很多是下面这种方法:
val subStr2 = 0000005096366
var countZero = 0 //统计subStr2中的前缀0的个数
subStr2.forEach outSideForEach@{
if(it == '0'){
++ countZero
}else{
return@outSideForEach //不为0时,跳出当前循环体
}
}
而结果呢,countZero最终值为6,为什么呢?因为在统计了5次之后countZero当前值累计到了5,但当循环执行到it == '5'时(5096366中)虽然return@outSideForEach该语句进行了return但只是跳出了当前的循环体,而当下一个it == '0' (5096366中的)时,还是会累计一次,因此countZero执行了++操作,最终countZero 的值为6。
因此,该方法并不可行,它只是结束掉了满足条件时的当前循环体,而非结束掉了外部循环。
正确方案
既然是想使用内部的某一条件达到时,需要结束最外层的循环,而非当前循环体,那么就来定义一个外部循环的执行体,当达到结束外部循环条件时,终结掉其生命,forEach不再往下执行。
val subStr2 = 0000005096366
var countZero = 0 //统计subStr2中的前缀0的个数
run outside@{
subStr2.forEach {
if(it == '0'){
++ countZero
}else{
return@outside //不为0时跳出forEach外部循环,不再进行遍历操作
}
}
}
方法封装
解决问题是次要,抓住和分析问题的痛点才是最难的。记录下来,以便抽查哈哈。最后将上述的解决方案封装成一个方法方便调用:
fun doStrThing(earTag:String) : String{
//截取指定字符串
val subStr1 = earTag.subSequence(2,earTag.length-2) //9840000005096366
val subStr2 = subStr1.subSequence(3,subStr1.length) //0000005096366
var countZero = 0 //统计subStr2中的前缀0的个数
run outside@{
subStr2.forEach {
if(it == '0'){
++ countZero
}else{
return@outside //不为0时跳出forEach循环
}
}
}
val subStr3 = subStr2.subSequence(countZero,subStr2.length) //5096366
return subStr3.toString()
}