如何解决Scala 2.10.x flatten问题

Bil*_*llz 2 scala flatten scala-2.10

在Scala 2.10.3中,我看到了这个问题.

Welcome to Scala version 2.10.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_25).
Type in expressions to have them evaluated.
Type :help for more information.


scala> val list = List(1, 2, List(5, 6))
list: List[Any] = List(1, 2, List(5, 6))

scala> list.flatten
<console>:9: error: No implicit view available from Any => scala.collection.GenTraversableOnce[B].
           list.flatten
                ^
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个问题?

我目前的解决方法是定义我自己的平面功能.

def flat(list: List[Any]): List[Any] = list flatten {
  case i: List[Any] => flat(i)
  case e => List(e)
}

scala> flat(list)
res2: List[Any] = List(1, 2, 5, 6)
Run Code Online (Sandbox Code Playgroud)

Jat*_*tin 10

嗯,这是不是一个问题,Scala 2.10.3但由于与每一个相当版本2.8.0flatten被引入.它表现得非常完美:

扁平化基本上做:

将此可遍历集合集合转换为由这些可遍历集合的元素组成的集合.

所以简而言之,你的类型A需要有一个A => GenTraversableOnce可以帮助你遍历它们的函数.在你的情况下:

scala> val x = List(1, 2, List(3, 4))
x: List[Any] = List(1, 2, List(3, 4))
Run Code Online (Sandbox Code Playgroud)

x是类型的List[Any],不可能Any像任何人一样拥有类型的泛型函数,每个人都有自己的定义.你可以做的是:(也适用于多个嵌套列表):

def flatten(ls: List[Any]): List[Any] = ls flatMap {
  case i: List[_] => flatten(i)
  case e => List(e)
}

val k = List(1, List(2, 3), List(List(List(List(4)), List(5)), List(6, 7)), 8)
flatten(k)
Run Code Online (Sandbox Code Playgroud)

它打印 List[Any] = List(1, 2, 3, 4, 5, 6, 7, 8)


dhg*_*dhg 6

你的解决方案有效 但是,总的来说,List[Any]看起来似乎是一种不受欢迎的情况. Any应该避免,因为它真的绕过了类型检查器为你做的好事.

更好的解决方案可能是使用专门设计的类层次结构:

sealed trait Tree {
  def flatten: List[Int]
}

case class Node(children: List[Tree]) extends Tree {
  def flatten = children.flatMap(_.flatten)
}

case class Leaf(n: Int) extends Tree {
  def flatten = List(n)
}
Run Code Online (Sandbox Code Playgroud)

然后:

val t = Node(List(Leaf(1), Leaf(2), Node(List(Leaf(5), Leaf(6)))))
t.flatten // List(1, 2, 5, 6)
Run Code Online (Sandbox Code Playgroud)

你也可以这样做:

def flat(t: Tree): List[Int] = t match {
  case Node(children) => children.flatMap(c => flat(c))
  case Leaf(n) => List(n)
}
Run Code Online (Sandbox Code Playgroud)

所以:

flat(t) // List(1, 2, 5, 6)
Run Code Online (Sandbox Code Playgroud)