【问题标题】:split a list of objects into different lists depending on a predicate splittor根据谓词拆分器将对象列表拆分为不同的列表
【发布时间】:2015-01-05 00:35:29
【问题描述】:

我有一个这样的列表:

val data = List("a","b","","c","d","e","","a","b","c")

我想把它从元素“”中拆分出来:

List(List("a","b"),List("c","d","e"),List("a","b","c"))

Scala 的方式是什么?

类似:

data.MAGIC(_=="")

【问题讨论】:

  • 你会一直想要删除与谓词匹配的元素吗?
  • 几乎是这个的复制品:stackoverflow.com/questions/21800041/…
  • @Paul 如果我们不能删除方法元素就可以了,因为我知道它总是输出列表的头。
  • 好的,在这种情况下你可以使用那个重复的问题吗?

标签: scala scala-collections


【解决方案1】:

使用span

def magic[T](l: List[T]): List[List[T]] = {
  @tailrec
  def magicAux[T](l: List[T], r: MutableList[List[T]]): MutableList[List[T]] = {
    val (p, s) = l.span(_ != "")
    s match {
      case Nil => r += p
      case _   => magicAux(s.tail, r += p)
    }
  }
  magicAux(l, new MutableList[List[T]]()).toList
}  

【讨论】:

  • 谢谢Jean,但我正在寻找某种收集方式,你认为有没有“更好”的方式
  • @Omid 如果你所说的“更好”是指标准库中的某些东西,那么没有任何东西可以做到这一点。如果有的话,它会是一个看起来像这样的方法。
【解决方案2】:

这个怎么样:

scala> Stream.iterate(""::data){ _.tail.dropWhile(_.nonEmpty) }
       .takeWhile(_.nonEmpty)
       .map{ _.tail.takeWhile(_.nonEmpty) }.toList
res1: List[List[String]] = List(List(a, b), List(c, d, e), List(a, b, c))

或者这个:

scala> (-1 +: data.zipWithIndex.collect{ case ("", i) => i } :+ data.size)
       .sliding(2).toList
       .map{ case List(h, t) => data.slice(h+1,t) }
res2: List[List[String]] = List(List(a, b), List(c, d, e), List(a, b, c))

还有这个:

scala> (data:+"").foldLeft(List[List[String]](), List[String]()){ 
         case((xs, x), v) => if(v.isEmpty) (x.reverse::xs, Nil) else (xs,v::x) 
       }._1.reverse
res3: List[List[String]] = List(List(a, b), List(c, d, e), List(a, b, c))

【讨论】:

    【解决方案3】:

    使用foldRight

      val res = ("" :: data).foldRight(List[List[_]](Nil))((x, s) =>
        (x, s) match {
          case ("", Nil :: _) => s
          case ("", _)        => Nil :: s
          case (x, h :: t)    => (x :: h) :: t
        }).tail
    

    【讨论】:

      猜你喜欢
      • 2011-01-05
      • 1970-01-01
      • 2018-10-24
      • 2023-04-11
      • 2010-10-09
      • 1970-01-01
      • 2022-12-21
      • 1970-01-01
      • 2018-03-13
      相关资源
      最近更新 更多