Scala List function for grouping consecutive identical elements

后端 未结 8 2247
悲&欢浪女
悲&欢浪女 2020-12-05 08:00

Given e.g.:

List(5, 2, 3, 3, 3, 5, 5, 3, 3, 2, 2, 2)

I\'d like to get to:

List(List(5), List(2), List(3, 3, 3), List(5, 5),         


        
相关标签:
8条回答
  • 2020-12-05 08:47

    This is the trick that I normally use:

    def split[T](list: List[T]) : List[List[T]] = list match {
      case Nil => Nil
      case h::t => val segment = list takeWhile {h ==}
        segment :: split(list drop segment.length)
    }
    

    Actually... It's not, I usually abstract over the collection type and optimize with tail recursion as well, but wanted to keep the answer simple.

    0 讨论(0)
  • 2020-12-05 08:50

    I have these implementations lying around from working on collections methods. In the end I checked in simpler implementations of inits and tails and left out cluster. Every new method no matter how simple ends up collecting a big tax which is hard to see from the outside. But here's the implementation I didn't use.

    import generic._
    import scala.reflect.ClassManifest
    import mutable.ListBuffer
    import annotation.tailrec
    import annotation.unchecked.{ uncheckedVariance => uV }
    
    def inits: List[Repr] = repSequence(x => (x, x.init), Nil)
    def tails: List[Repr] = repSequence(x => (x, x.tail), Nil)
    def cluster[A1 >: A : Equiv]: List[Repr] =
      repSequence(x => x.span(y => implicitly[Equiv[A1]].equiv(y, x.head)))
    
    private def repSequence(
      f: Traversable[A @uV] => (Traversable[A @uV], Traversable[A @uV]),
      extras: Traversable[A @uV]*): List[Repr] = {
    
      def mkRepr(xs: Traversable[A @uV]): Repr = newBuilder ++= xs result
      val bb = new ListBuffer[Repr]
    
      @tailrec def loop(xs: Repr): List[Repr] = {
        val seq = toCollection(xs)
        if (seq.isEmpty)
          return (bb ++= (extras map mkRepr)).result
    
        val (hd, tl) = f(seq)
        bb += mkRepr(hd)
        loop(mkRepr(tl))
      }
    
      loop(self.repr)
    }
    

    [Edit: I forget other people won't know the internals. This code is written from inside of TraversableLike, so it wouldn't run out of the box.]

    0 讨论(0)
提交回复
热议问题