删除scala中连续的相同元素



我有一个列表,其中可能包含某些连续的相同元素。我想用一个元素替换许多连续的相同元素。如何在scala 中进行

假设我的列表是

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

我想要输出列表作为

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

使用sliding:可以非常干净地完成

myList.head :: myList.sliding(2).collect { case Seq(a,b) if a != b => b }.toList

它会查看所有的对,对于每个不匹配的对(a,b),它会返回b。但是,它必须把原来的a放在列表的前面。

一种方法就是这样

我相信还有更好的方法。

list.tail.foldLeft(List[Int](list.head))((prev, next) => {
  if (prev.last != next) prev +: next
  else prev
})

foldLeft取一个参数(在第一个应用程序中),从左到右遍历列表,将prevnext应用于给定的双参数函数,其中prev是迄今为止函数的结果,next是列表中的下一个元素。

另一种方式:

list.zipWithIndex.filter(l => (l._2 == 0) || (l._1 != list(l._2-1))).map(_._1)

通常,list.zip(otherList)返回相应元素的元组列表。例如,List(1,2,3).zip(List(4,5,6))将产生List((1,4), (2,5), (3,6))zipWithIndex是一个特定的函数,它将每个列表元素与其索引附加在一起,从而产生一个列表,其中每个元素的形式为(original_list_element, index)

CCD_ 15返回仅包含为CCD_ 17返回CCD_ 16的元素的列表。我给出的函数只是检查这个元素是否等于原始列表中的前一个元素(或者索引为0)。

最后,.map(_._1)只是删除了索引。

val myList = List(5, 7, 2, 3, 3, 3, 5, 5, 3, 3, 2, 2, 2)
myList.foldRight[List[Int]](Nil) { case (x, xs) =>
  if (xs.isEmpty || xs.head != x) x :: xs else xs }
// res: List[Int] = List(5, 7, 2, 3, 5, 3, 2)

(答案从该副本中移出)

这是的一个变体

  • 尾部递归
  • 不使用库中的任何方法(无论好坏)

代码:

def compress[A](xs: List[A]): List[A] = {
  @annotation.tailrec 
  def rec(rest: List[A], stack: List[A]): List[A] = {
    (rest, stack) match {
      case (Nil, s) => s
      case (h :: t, Nil) => rec(t, List(h))
      case (h :: t, a :: b) => 
        if (h == a) rec(t, stack) 
        else rec(t, h :: stack)
    }
  }
  rec(xs, Nil).reverse
}

示例

println(compress(List('a, 'a, 'a, 'a, 'b, 'c, 'c, 'a, 'a, 'd, 'e, 'e, 'e, 'e)))

产生以下输出:

List('a, 'b, 'c, 'a, 'd, 'e)
val l = List(5, 7,2, 3, 3, 3, 5, 5, 3, 3, 2, 2, 2)
def f(l: List[Int]): List[Int] = l match {
  case Nil => Nil
  case x :: y :: tail if x == y => f(y::tail)
  case x :: tail => x :: f(tail)
}
println(f(l)) //List(5, 7, 2, 3, 5, 3, 2)

当然,你可以让它成为递归的尾部

import scala.collection.mutable.ListBuffer
object HelloWorld {
  def main(args:Array[String]) {
  val lst=List(5, 7, 2, 3, 3, 3, 5, 5, 3, 3, 2, 2, 2)
  val lstBf=ListBuffer[Int](lst.head)
  for(i<-0 to lst.length-2){
    if(lst(i)!=lst(i+1)){
      lstBf+=lst(i+1)
  }
  }
  println(lstBf.toList)
}
}

试试这个,

val y = list.sliding(2).toList
  val x =y.filter(x=> (x.head != x.tail.head)).map(_.head) :+ (y.reverse.filter(x=> x.head !=x.tail.head)).head.tail.head

另一种变体

val is = List(5, 7,2, 3, 3, 3, 5, 5, 3, 3, 2, 2, 2)
val ps = is.head::((is zip is.tail) collect { case (a,b) if a != b => b })
//> ps  : List[Int] = List(5, 7, 2, 3, 5, 3, 2)

is zip is.tail正在执行与.sliding(2)类似的操作)

最新更新