如何在Scala中迭代列表列表?

时间:2010-02-20 21:32:39

标签: generics scala list

我正在尝试为在Scala中保存列表的列表对象实现我自己的通用flatten。 此时我已经

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

我收到一条消息:

  

找到xs找到单位所需列表。

3 个答案:

答案 0 :(得分:23)

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

答案 1 :(得分: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)

<强>更新

顺便说一句,List[List[T]]可以展平为List[T]的事实是List是Monad的原因的50%。通常,这称为join。另外50%来自于您可以在A => B之间映射函数List[A]以产生List[B]。通用名称是Functor mapfmap and join on Wikipedia

为类型构造函数M定义Monad的另一种方法是使用pure操作,其值为A,并返回M[A];以bind操作,M[A],一个函数A => M[B],并生成M[B]。对于列表,pure == List(_)bind = (l: List[A], f: (A => List[B])) => l.flatMap(f)

答案 2 :(得分:6)

就个人而言,我喜欢这种风格:

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