String scala中的takeRightWhile()方法
我可能遗漏了一些东西,但最近我遇到了一个任务,根据某些条件获取最后的符号。例如,我有一个字符串:String scala中的takeRightWhile()方法,string,scala,String,Scala,我可能遗漏了一些东西,但最近我遇到了一个任务,根据某些条件获取最后的符号。例如,我有一个字符串:“这是分隔的\u值\u 5”。现在我想将5提取为Int 注:未定义由分隔的零件数量 如果我在一个字符串上有一个方法takerRightWhile(f:Char=>Boolean),那么它就很简单了:takerRightWhile(ch=>ch!=''.'''.'''.'。此外,它将是有效的:一个简单的实现实际上包括查找\uu的最后一个索引并获取一个子字符串,而使用此方法将节省第一步并提供更好的平均时间
“这是分隔的\u值\u 5”
。现在我想将5
提取为Int
注:未定义由分隔的零件数量
如果我在一个字符串上有一个方法takerRightWhile(f:Char=>Boolean)
,那么它就很简单了:takerRightWhile(ch=>ch!=''.'''.'''.'
。此外,它将是有效的:一个简单的实现实际上包括查找\uu
的最后一个索引并获取一个子字符串,而使用此方法将节省第一步并提供更好的平均时间复杂度
更新:伙计们,所有的str.reverse.takeWhile(!='''.'''.reverse
的变体都非常低效,因为你实际上使用了额外的O(n)
空间。如果您想有效地实现方法takerightwile
,您可以从右侧开始迭代,在字符串生成器中累积结果,然后返回结果。我问的是这种方法,而不是问题本身已经描述和拒绝的实现
问题:scala标准库中是否存在这种方法?如果没有,是否有来自标准库的方法组合,以在最小行数上实现相同的效果
提前感谢。可能的解决方案:
str.reverse.takeWhile(_!='_').reverse
更新
您可以使用foldRight使用以下表达式从右向左移动:
str.toList.foldRight(List.empty[Char]) {
case (item, acc) => item::acc
}
在这里,您需要检查条件并在条件满足后停止添加项目。为此,您可以将一个标志传递给累加值:
val (_, list) = str.toList.foldRight((false, List.empty[Char])) {
case (item, (false, list)) if item!='_' => (false, item::list)
case (_, (_, list)) => (true, list)
}
val res = list.mkString.toInt
此解决方案比双反转的解决方案效率更低:
foldRight的实现使用列表反转和foldLeft的组合
您不能中断foldRight执行,所以需要在满足条件后跳过所有项的标志
可能的解决办法:
str.reverse.takeWhile(_!='_').reverse
更新
您可以使用foldRight使用以下表达式从右向左移动:
str.toList.foldRight(List.empty[Char]) {
case (item, acc) => item::acc
}
在这里,您需要检查条件并在条件满足后停止添加项目。为此,您可以将一个标志传递给累加值:
val (_, list) = str.toList.foldRight((false, List.empty[Char])) {
case (item, (false, list)) if item!='_' => (false, item::list)
case (_, (_, list)) => (true, list)
}
val res = list.mkString.toInt
此解决方案比双反转的解决方案效率更低:
foldRight的实现使用列表反转和foldLeft的组合
您不能中断foldRight执行,所以需要在满足条件后跳过所有项的标志
您可以使用StringBuilder和lastIndexWhere
val str = "this_is_separated_values_5"
val sb = new StringBuilder(str)
val lastIdx = sb.lastIndexWhere(ch => ch != '_')
val lastCh = str.charAt(lastIdx)
您可以使用StringBuilder和lastIndexWhere
val str = "this_is_separated_values_5"
val sb = new StringBuilder(str)
val lastIdx = sb.lastIndexWhere(ch => ch != '_')
val lastCh = str.charAt(lastIdx)
我同意这一点:
val s = "string_with_following_number_42"
s.split("_").reverse.head
// res:String = 42
这是一种幼稚的尝试,绝不是优化的。它所做的是将字符串
拆分为字符串
的数组
,将其反转并获取第一个元素。请注意,因为反转发生在拆分之后,所以字符的顺序是正确的。我会这样说:
val s = "string_with_following_number_42"
s.split("_").reverse.head
// res:String = 42
这是一种幼稚的尝试,绝不是优化的。它所做的是将字符串
拆分为字符串
的数组
,将其反转并获取第一个元素。请注意,因为反转发生在拆分之后,所以字符的顺序是正确的。我不能确切地确定您所面临的问题。我的理解是,您希望有一个字符串的格式xxx\u xxx\u xx\u123
,并且您希望提取最后的部分作为Int
import scala.util.Try
val yourStr = "xxx_xxx_xxx_xx...x_xxxxx_123"
val yourInt = yourStr.split('_').last.toInt
// But remember that the above is unsafe so you may want to take it as Option
val yourIntOpt = Try(yourStr.split('_').last.toInt).toOption
或者。。。假设您的要求是收集一个右后缀
,直到某个布尔条件保持true
import scala.util.Try
val yourStr = "xxx_xxx_xxx_xx...x_xxxxx_123"
val rightSuffix = yourStr.reverse.takeWhile(c => c != '_').reverse
val yourInt = rightSuffix.toInt
// but above is unsafe so
val yourIntOpt = Try(righSuffix.toInt).toOption
如果您的要求与此不同,请发表评论。我不能确切确定您所面临的问题。我的理解是,您希望有一个字符串的格式xxx\u xxx\u xx\u123
,并且您希望提取最后的部分作为Int
import scala.util.Try
val yourStr = "xxx_xxx_xxx_xx...x_xxxxx_123"
val yourInt = yourStr.split('_').last.toInt
// But remember that the above is unsafe so you may want to take it as Option
val yourIntOpt = Try(yourStr.split('_').last.toInt).toOption
或者。。。假设您的要求是收集一个右后缀
,直到某个布尔条件保持true
import scala.util.Try
val yourStr = "xxx_xxx_xxx_xx...x_xxxxx_123"
val rightSuffix = yourStr.reverse.takeWhile(c => c != '_').reverse
val yourInt = rightSuffix.toInt
// but above is unsafe so
val yourIntOpt = Try(righSuffix.toInt).toOption
如果您的要求与此不同,请进行注释。您是否对此进行了测试?因为如果在最后一个\uu
-OP后面有多个字符,那么它就不起作用了。OP显然想要字符串的其余部分,而不是最后一个字符,否则只需要获取最后一个字符即可!。也没有必要使用StringBuilder,lastIndexWhere
处理字符串。@TheArchetypalPaul我误解了这个问题。我首先在StringBuilder
中找到了lastIndexWhere
,但没有选中StringOps
。谢谢你指出它们。你测试过这个吗?因为如果在最后一个\uu
-OP后面有多个字符,那么它就不起作用了。OP显然想要字符串的其余部分,而不是最后一个字符,否则只需要获取最后一个字符即可!。也没有必要使用StringBuilder,lastIndexWhere
处理字符串。@TheArchetypalPaul我误解了这个问题。我首先在StringBuilder
中找到了lastIndexWhere
,但没有选中StringOps
。谢谢你指出,谢谢你的回答。请查看问题的更新。非常感谢更新。至少它不会创建新字符串,所以它比以前的解决方案更有效。也许可以将其简化为尾部递归和StringBuilder以提高时间复杂性(换句话说,终止foldRight)?谢谢您的回答。请查看问题的更新。非常感谢更新。至少它不会创建新字符串,所以它比以前的解决方案更有效。也许可以将其简化为尾部递归和StringBuilder以提高时间复杂性(换句话说,终止foldRight)?谢谢您的回答。然而,拆分比.reverse.take.reverse方法更糟糕。不过,感谢您指向“尝试”。实际上,如果您的要求是在s上拆分,则拆分方法会更好