2017-03-08 247 views
0

如果我是分割字符串,我能做到斯卡拉通用「串分」的方法

"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 
    } 
) 

分裂在這種情況下不存在,但它讓我想起了跨度,分區,GROUPBY,但只有跨度似乎接近,但它不處理的領先/結束逗號優雅。

回答

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())

+0

對Meghana的接受,因爲它對我來說似乎更易讀+它不需要創建多個tuple2。 –

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)) 
    } 
    } 
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))