2014-12-28 48 views
0

在Scala中,你怎麼能這樣扁平化:如何壓扁列表[任何]?

List(1, List(2, 3), 4, List(5, 6, 7)) 

這個

List(1, 2, 3, 4, 5, 6, 7) 

+6

如果您可以避免結束使用List [Any]首先你的生活會好很多。 –

+4

首先將它轉換爲一個理智的數據類型,然後使用常規的'flatten'方法? –

回答

3

scala99 problems

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

flatten(List(1, List(2,3), 4, List(5,6,7)))  //> res0: List[Any] = List(1, 2, 3, 4, 5, 6, 7) 
+0

就是這樣,謝謝。 –

-2

你應該使用的Either[Int, List[Int]]列表:

val xs: List[Either[Int, List[Int]]] = List(Left(1), Left(2), Right(List(1, 2, 3)), Left(7)) 
val xs1 = xs.flatMap { 
    case Left(i) => List(i) 
    case Right(is) => is 
} 

在另一方面,你也許可以通過在首位不產生這樣的異構列表來解決這個問題。

可選:

隨着Scalaz的\/,更換Either[Int, List[Int]]Int \/ List[Int]

val xs: List[Int \/ List[Int]] = ... 

val xs1 = xs.map { 
    case -\/(i) => ... 
    case \/-(is) => ... 
} 
+0

爲什麼地獄沒有評論? –

+2

Downvotes不需要評論。我的是Scalaz需要改變輸入列表的類型,我們有兩個問題:( –

+0

斯卡拉茲位是可選的!) –

2

的一般解如果你必須處理Any,您可以通過模式在運行時匹配這樣做:

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

但作爲@Erik說,這最好始終跟蹤類型信息,以便確保您正確處理所有情況。對於Erik解決方案的更一般版本,您可以使用無形:https://github.com/milessabin/shapeless/blob/master/examples/src/main/scala/shapeless/examples/flatten.scala(該示例使用元組,但是與HList s的工作方式相同)