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

top*_*ess 17 generics scala list

我正在尝试为在Scala中保存列表的列表对象实现我自己的通用flatten.在这一点上,我有

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

我收到一条消息:

为xs找到单位所需列表.

Vik*_*ang 23

def myFlatten[T](list : List[List[T]]) = for(xs <- list; x <- xs) yield x
Run Code Online (Sandbox Code Playgroud)


ret*_*nym 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]
Run Code Online (Sandbox Code Playgroud)

或者使用内置的 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)
Run Code Online (Sandbox Code Playgroud)

看看如何在没有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)
Run Code Online (Sandbox Code Playgroud)

UPDATE

顺便说一句,List[List[T]]可以被夷为平地的事实是Monad List[T]原因的50%List.通常,这被称为join.另外50%来自于一个事实可以映射功能A => B跨越List[A]到导致List[B].这个的一般名称是Functor map.fmap并加入维基百科.

为类型构造函数定义Monad的另一种方法M是使用一个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)


Dan*_*ral 6

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

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