Scala generic" string split"方法

时间:2017-03-08 14:21:44

标签: scala scala-collections

如果我分裂一个字符串,我就可以

"123,456,789".split(",") 

得到 Seq("123","456","789")

将字符串视为一系列字符,如何将其推广到其他对象序列?

val x = Seq(One(),Two(),Three(),Comma(),Five(),Six(),Comma(),Seven(),Eight(),Nine())
x.split(
  number=>{
    case _:Comma => true
    case _ => false
  }
)
在这种情况下,

分裂并不存在,但它让我想起了span,partition,groupby,但只有span似乎很接近,但它并没有优雅地处理前导/结尾逗号。 / p>

3 个答案:

答案 0 :(得分:1)

以下是'a'解决方案,而不是最优雅的解决方案 -

def split[A](x: Seq[A], edge: A => Boolean): Seq[Seq[A]] = { 

  val init = (Seq[Seq[A]](), Seq[A]())

  val (result, last) = x.foldLeft(init) { (cum, n) =>
    val (total, prev) = cum

    if (edge(n)) {
        (total :+ prev, Seq.empty)
    } else {
        (total, prev :+ n)
    }
  }

  result :+ last
}

示例结果 -

scala> split(Seq(1,2,3,0,4,5,0,6,7), (_:Int) == 0)
res53: Seq[Seq[Int]] = List(List(1, 2, 3), List(4, 5), List(6, 7))

答案 1 :(得分:1)

implicit class SplitSeq[T](seq: Seq[T]){
  import scala.collection.mutable.ListBuffer
  def split(sep: T): Seq[Seq[T]] = {
    val buffer = ListBuffer(ListBuffer.empty[T])
    seq.foreach {
      case `sep` => buffer += ListBuffer.empty
      case elem => buffer.last += elem
    }; buffer.filter(_.nonEmpty)
  }
}

然后可以像x.split(Comma())一样使用。

答案 2 :(得分:0)

这是我过去的解决方法,但我怀疑有更好/更优雅的方式。

  def break[A](xs:Seq[A], p:A => Boolean): (Seq[A], Seq[A]) = {
    if (p(xs.head)) {
      xs.span(p)
    }
    else {
      xs.span(a => !p(a))
    }
  }