2010-02-20 50 views
16

我想實現我自己的通用平展的列表對象,其中列舉斯卡拉列表。 在這一點上我有如何在Scala中迭代列表的列表?

def myFlatten[T](list: List[List[t]]): List[T] = { 
    for (xs <- list) 
     for (x <- xs) yield x 
} 

我得到一個消息:

爲XS找到所需的設備列表中。

回答

23
def myFlatten[T](list : List[List[T]]) = for(xs <- list; x <- xs) yield x 
12

非常接近!這裏有一個工程:

scala> def myFlatten[T](list: List[List[T]]): List[T] = for (xs <- list; x <- xs) yield x 
myFlatten: [T](list: List[List[T]])List[T] 

或者使用內置的flatten

scala> List(List(1, 2), List(3)).flatten 
res0: List[Int] = List(1, 2, 3) 

scala> List(Set(1, 2), Set(3)).flatten 
res1: List[Int] = List(1, 2, 3) 

這是有益的,看看如何寫這個功能,而不for語法糖。

scala> def myFlatten[T](list: List[List[T]]): List[T] = list flatMap identity 
myFlatten: [T](list: List[List[T]])List[T] 

scala> myFlatten(List(List(1, 2), List(3))) 
res3: List[Int] = List(1, 2, 3) 

UPDATE

順便說一句,事實List[List[T]]可以展平到List[T]是那List是單子的原因的50%。通常,這被稱爲join。另外50%來自您可以通過List[A]映射功能A => B以導致List[B]的事實。通用名稱爲Functor mapfmap and join on Wikipedia

爲類型構造函數M定義Monad的另一種方法是使用pure操作,該操作的值爲A,並返回M[A];以及需要M[A],函數A => M[B]並且結果爲M[B]bind操作。對於列表,pure == List(_),並bind = (l: List[A], f: (A => List[B])) => l.flatMap(f)

6

就個人而言,我很喜歡這種風格:

def myFlatten[T](list: List[List[t]]): List[T] = for { 
    xs <- list 
    x <- xs 
} yield x