将字符串拆分为组

djh*_*rld 12 string scala

我试图将一个字符串"分组"成段,我想这个例子会更加简洁地解释它

scala> val str: String = "aaaabbcddeeeeeeffg"
... (do something)
res0: List("aaaa","bb","c","dd","eeeee","ff","g")
Run Code Online (Sandbox Code Playgroud)

我可以通过几种方式以命令式的方式执行此操作(使用vars并单步执行字符串以查找组)但我想知道是否可以获得更好的功能解决方案?我一直在浏览Scala API,但似乎没有适合我需求的东西.

任何帮助,将不胜感激

Tho*_*ung 21

您可以使用span递归地拆分字符串:

def s(x : String) : List[String] = if(x.size == 0) Nil else {
    val (l,r) = x.span(_ == x(0))
    l :: s(r) 
}
Run Code Online (Sandbox Code Playgroud)

尾递归:

@annotation.tailrec def s(x : String, y : List[String] = Nil) : List[String] = {
    if(x.size == 0) y.reverse 
    else {
        val (l,r) = x.span(_ == x(0))
        s(r, l :: y)
    }
}
Run Code Online (Sandbox Code Playgroud)


ten*_*shi 16

似乎所有其他答案都非常集中在收集操作上.但纯字符串+正则表达式解决方案更简单:

str split """(?<=(\w))(?!\1)""" toList
Run Code Online (Sandbox Code Playgroud)

在这个正则表达式中,我对捕获的char 使用正向lookbehind负向前瞻

  • 而且令人惊讶的不可读性.你真的可以说你明白那个没有仔细研究的人. (9认同)
  • @Paul:我同意,但请考虑一下:如果你使用上面的代码是真的,你可以把它放在一个方法中,给它一个好名字`splitByGroup`,对它进行文档和单元测试.想要拆分字符串的人不必理解正则表达式,只要`splitByGroup`的实现者这样做. (3认同)
  • +1 - 非常好!我总是忘记正则表达式的惊人力量. (2认同)

Mar*_*ing 13

def group(s: String): List[String] = s match {
  case "" => Nil
  case s  => s.takeWhile(_==s.head) :: group(s.dropWhile(_==s.head))
}
Run Code Online (Sandbox Code Playgroud)

编辑:尾递归版:

def group(s: String, result: List[String] = Nil): List[String] = s match {
  case "" => result reverse
  case s  => group(s.dropWhile(_==s.head), s.takeWhile(_==s.head) :: result)
}
Run Code Online (Sandbox Code Playgroud)

可以像其他参数一样使用,因为第二个参数具有默认值,因此不必提供.