How to group a variable-length, repeating sequence in Scala

后端 未结 4 1555
生来不讨喜
生来不讨喜 2020-12-31 22:14

I have a collection of ints that repeat themselves in a pattern:

val repeatingSequence = List(1,2,3,1,2,3,4,1,2,1,2,3,4,5)

I\'d like to sec

相关标签:
4条回答
  • 2020-12-31 22:58
    import scala.collection.mutable.ListBuffer
    import scala.collection.breakOut
    
    val repeatingSequence = List(1,2,3,1,2,3,4,1,2,1,2,3,4,5)
    val groupedBySequence: List[List[Int]] = repeatingSequence.foldLeft(ListBuffer[ListBuffer[Int]]()) {
      case (acc, 1) => acc += ListBuffer(1)
      case (acc, n) => acc.last += n; acc
    }.map(_.toList)(breakOut)
    
    0 讨论(0)
  • 2020-12-31 22:59

    Here's a not-exactly-elegant solution I bashed out using span:

    def groupWhen[A](fn: A => Boolean)(xs: List[A]): List[List[A]] = {
      xs.span(!fn(_)) match {
        case (Nil, Nil) => Nil
        case (Nil, z::zs) => groupWhen(fn)(zs) match {
          case ys::yss => (z::ys) :: yss
          case Nil => List(List(z))
        }
        case (ys, zs) => ys :: groupWhen(fn)(zs)
      }
    }
    
    scala> groupWhen[Int](_==1)(List(1,2,3,1,2,3,4,1,2,3,4,5))
    res39: List[List[Int]] = List(List(1, 2, 3), List(1, 2, 3, 4), List(1, 2, 3, 4, 5))
    
    scala> groupWhen[Int](_==1)(List(5,4,3,2,1,2,3,1,2,3,4,1,2,3,4,5))
    res40: List[List[Int]] = List(List(5, 4, 3, 2), List(1, 2, 3), List(1, 2, 3, 4), List(1, 2, 3, 4, 5))
    
    0 讨论(0)
  • 2020-12-31 23:02

    Given an iterator itr, this will do the trick:

    val head = iter.next()
    val out = (
      Iterator continually {iter takeWhile (_ != head)}
      takeWhile {!_.isEmpty}
      map {head :: _.toList}
    ).toList
    
    0 讨论(0)
  • 2020-12-31 23:05

    As well all know, fold can do everything... ;)

      val rs = List(1,2,3,1,2,3,4,1,2,1,2,3,4,5)
      val res = (rs++List(1)).foldLeft((List[List[Int]](),List[Int]()))((acc,e) => acc match {
        case (res,subl) => {
          if (e == 1) ((subl.reverse)::res,1::Nil) else (res, e::subl)
        }
      })
      println(res._1.reverse.tail)
    

    Please regard this as an entry for the obfuscated Scala contest rather than as a real answer.

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