Scala-模式匹配和For循环问题

Scala-模式匹配和For循环问题,scala,for-loop,pattern-matching,Scala,For Loop,Pattern Matching,我正在努力解决12的问题 给定问题P10中指定的运行长度代码列表, 构造其未压缩版本。例如: 我试图对列表中的元素进行模式匹配,然后使用for循环连接字符,但第5行出现以下编译错误: type mismatch; found : scala.collection.immutable.IndexedSeq[List[A]] required: List[A] 1 def decode[A](xs:List[(Int,A)]):List[A]=xs匹配{ 2情况无=>无 3案例x::xs

我正在努力解决12的问题

给定问题P10中指定的运行长度代码列表, 构造其未压缩版本。例如:

我试图对列表中的元素进行模式匹配,然后使用for循环连接字符,但第5行出现以下编译错误:

type mismatch;  found   : scala.collection.immutable.IndexedSeq[List[A]]  required: List[A]

1 def decode[A](xs:List[(Int,A)]):List[A]=xs匹配{
2情况无=>无
3案例x::xs=>{
4为{

5我你很接近-只是几个问题。下面是我提出的一个固定版本:

def decode[A](xs: List[(Int, A)]) : List[A] = xs match {
   case Nil => Nil
   case x :: xs => (for {
                       i <- 1 to x._1
                    } yield (x._2)).toList ::: decode(xs)
}
def decode[A](xs:List[(Int,A)]):List[A]=xs匹配{
案例Nil=>Nil
案例x::xs=>(对于{

i主要问题是用于连接列表的运算符-
仅用于将单个元素预先添加到列表中,因此在代码中,您试图将收益率的结果(它本身是一个序列)预先添加到
列表[a]
,从而导致类型不兼容。这是一个可以工作的修改版本-它使用运算符
+:
,可以将两个序列连接在一起。我还将
yield
移动到一个单独的语句中,否则需要在yield周围加括号,以便
+:
处理
会产生
,而不是在每个元素上(由于类型不匹配,该元素也不会编译)

def decode[A](xs:List[(Int,A)]):List[A]=xs匹配{
案例Nil=>Nil
案例x::xs=>{
val repeatedElems=for{

我其他答案都很好,但我认为使用
List.fill
生成解码列表需要更少的语法,并且比使用
的yield
表达式更容易理解

def decode[A](xs: List[(Int, A)]) : List[A] = xs match {
   case Nil => Nil
   case x :: xs => List.fill(x._1)(x._2) ::: decode(xs)
}
输出:

scala> decode(List((4, 'a), (1, 'b), (2, 'c), (2, 'a), (1, 'd), (4, 'e)))
res0: List[Symbol] = List('a, 'a, 'a, 'a, 'b, 'c, 'c, 'a, 'a, 'd, 'e, 'e, 'e, 'e)

下面是Brian答案的一个稍加修改的版本。分解元组使代码更具可读性:

def decode[A](xs: List[(Int, A)]) : List[A] = xs match {
   case Nil => Nil
   case (count, letter) :: xs => List.fill(count)(letter) ::: decode(xs)
}

另一种方法是使用map:

def decode[A](l: List[(Int, A)]): List[A] = {
  val l1: List[List[A]] = l map { e =>
    List.fill(e._1)(e._2)
  }
  l1.flatten
} 

(由于github在注释中对代码格式做了非常糟糕的事情,所以没有内联发布)谢谢你的答案=)也谢谢你的答案!=)我只能接受一个答案,所以我将向上投票你的答案=)flatMap将更具可读性(根本没有中间变量)
scala> decode(List((4, 'a), (1, 'b), (2, 'c), (2, 'a), (1, 'd), (4, 'e)))
res0: List[Symbol] = List('a, 'a, 'a, 'a, 'b, 'c, 'c, 'a, 'a, 'd, 'e, 'e, 'e, 'e)
def decode[A](xs: List[(Int, A)]) : List[A] = xs match {
   case Nil => Nil
   case (count, letter) :: xs => List.fill(count)(letter) ::: decode(xs)
}
def decode[A](l: List[(Int, A)]): List[A] = {
  val l1: List[List[A]] = l map { e =>
    List.fill(e._1)(e._2)
  }
  l1.flatten
}