从元组构建列表

时间:2016-04-13 01:15:52

标签: scala

我试图解决从here

中获取的问题12

总结一下,给出一个元组列表:

List((4, 'a), (1, 'b), (2, 'c), (2, 'a), (1, 'd), (4, 'e))

结果应该是一个包含_2重复_1次

中每个元素的列表

结果为List('a, 'a, 'a, 'a, 'b, 'c, 'c, 'a, 'a, 'd, 'e, 'e, 'e, 'e)

这是我的尝试(见code online

object P12 extends App  {

    val ls2 = List((4, 'a), (1, 'b), (2, 'c), (2, 'a), (1, 'd), (4, 'e))

    println(ls2)
    println(decode(ls2))   

    def decode[A] (list: List[(Int,A)]): List[A] = {
        list.foldLeft(List[A]()) { (result, elem) => for ( n <- 1 to elem._1) result :+ elem._2 }
    }

}

我收到以下错误:

Main.scala:9: error: type mismatch;
 found   : Unit
 required: List[A]
list.foldLeft(List[A]()) { (result, elem) => for ( n <- 1 to elem._1) result :+ elem._2 }

如何解决这个问题?

3 个答案:

答案 0 :(得分:3)

使用List.fillflatMap

val l = List((4, 'a), (1, 'b), (2, 'c), (2, 'a), (1, 'd), (4, 'e))
l.flatMap { t => List.fill(t._1)(t._2) }

答案 1 :(得分:1)

你的for周期什么也没做,你是否正在以不可变的集合的命令方式使用它。在每次迭代中,您使用附加元素从result创建新集合,然后将其丢弃。您for的结果是Unit,因此错误。

执行任务的正确功能方法是:

def decode[A] (list: List[(Int,A)]): List[A] = {
  list.foldLeft(List[A]()) { case (result, (count, el)) =>
    result ::: (1 to count).map(_ => el).toList
  }
}

UPD :另请注意,List上的附加操作需要线性时间,因此整个decode变为O(n 2

使用flatMap

,可以更有效,更简洁地执行任务
def decode[A](list: List[(Int, A)]): List[A] =
  list.flatMap { case (count, el) => (1 to count).map(_ => el) }

答案 2 :(得分:1)

这个递归函数在两种情况下简明扼要地表示(或列出)语义,

def decode( xs: List[(Int,Symbol)] ): List[Symbol] = xs match {
  case Nil => Nil
  case (x :: xss) => List.fill(x._1)(x._2) ++ decode(xss) 
}

空列表导致空列表,否则对于非空列表的head元素,将其展开为重复元素列表,并将其添加到已解码列表的其余部分。< / p>