【问题标题】:Flattening of list in scalascala中列表的展平
【发布时间】:2018-04-15 11:07:06
【问题描述】:

我已经跳入 Scala 并开始做 scala99,但我被困在 P07(列表展平)以下是我的代码和来自 repl 的错误消息

scala> def flatten[A](x: List[A]): List[A] =
 | for(i <- x) yield i match {
 | case lst: List[Any] => flatten(lst)
 | case e => List(e)
 | }
<console>:12: error: type mismatch;
found   : List[List[Any]]
required: List[A]
   for(i <- x) yield i match {
         ^

我哪里错了,正确的方法是什么? 谢谢。

【问题讨论】:

  • 我首先看到的是你的参数类型是List[A]而不是List[List[A]],因为前者没有什么可以“扁平化”的。另外,为什么要匹配List[Any]
  • @YuvalItzchakov 我不明白:为什么期待 List[Any] 在那个地方?当xList[A] 时,for(i &lt;- x) 完全有效 ...

标签: scala flatten


【解决方案1】:

就像我在对你的问题的评论中所说的那样,我不知道为什么编译器会这样抱怨,但问题的根源在于你返回的类型与输入相同:如果你扁平化 @987654321 @ 输出将是List[Int],那么A 在你的代码中会是什么???

我不认为类型参数在这种情况下真的有任何用途,你最好只使用List[Any]

  def flatten(in: List[Any], out: List[Any] = Nil): List[Any] = in match { 
    case Nil => out.reverse
    case Nil :: t => flatten(t, out)
    case (h :: t) :: tail => flatten(h :: t ::: tail, out)
    case h :: t => flatten(t, h :: out)
  }

【讨论】:

    【解决方案2】:

    我会用这样的东西

    def flatten(t: List[Any]): List[Any]
      = t.flatMap {
            case s: List[_] => flatten(s)
            case x => List(x)
          }
    

    在您的情况下,编译器会抱怨,因为函数体清楚地返回了 List[List[_]] 类型的值,并且没有任何东西可以使 A 从该类型派生。同时,您不能使 A 从 List 派生,因为顶级列表可能包含标量值。最后,您的代码实际上并没有展平输入,它只是将每个标量值包装在单个元素列表中。

    【讨论】:

    • 第一个case 应该是=&gt; s。另外,这实际上并不能回答问题...
    • @Dima nope,根据问题定义,它不应该因为嵌套深度没有限制。
    • @AlexK 我想在不使用flatMap的情况下解决这个问题。
    • @AlexK 我只是想要一个替代方案,Scala 99 网站上还提供了使用flatMap 的解决方案,如果我只是想要一个解决方案,那么为什么我在这里发布我的问题!
    猜你喜欢
    • 1970-01-01
    • 2016-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-13
    • 2014-12-30
    • 2018-02-11
    相关资源
    最近更新 更多