Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String scala中的takeRightWhile()方法_String_Scala - Fatal编程技术网

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上拆分,则拆分方法会更好