在scala中展平和flatMap

时间:2016-12-07 22:15:26

标签: scala flatten flatmap

我想检查一下我是否正确理解了flatten和flatMap函数。

1)我是否认为flatten仅在集合构成其他集合时才起作用。例如,flatten可用于以下列表

//list of lists
val l1 = List(List(1,1,2,-1,3,1,-4,5), List("a","b"))

//list of a set, list and map
val l2 = List(Set(1,2,3), List(4,5,6), Map('a'->"x",'b'->"y"))

但flatten不适用于以下

val l3 = List(1,2,3)
val l4 = List(1,2,3,List('a','b'))
val s1 = "hello world"
val m1 = Map('h'->"h", 'e'->"e", 'l'->"l",'o'->"0")

'平坦化'方法将通过删除层次结构创建一个包含所有元素的新列表。因此,它会变得平坦。集合并将所有元素集中在同一级别。

l1.flatten
res0: List[Any] = List(1, 1, 2, -1, 3, 1, -4, 5, a, b)

l2.flatten
res1: List[Any] = List(1, 2, 3, 1, 5, 6, (a,x), (b,y))

2)' flatMap'首先将方法应用于列表的元素,然后展平列表。正如我们上面提到的,如果列表具有层次结构(包含其他集合),则flatten方法可以工作。因此,重要的是我们应用于元素的方法返回一个集合,否则flatMap将不起作用

//we have list of lists
val l1 = List(List(1,1,2,-1,3,1,-4,5), List("a","b"))

l1 flatMap(x=>x.toSet)
res2: List[Any] = List(5, 1, -4, 2, 3, -1, a, b)

val l2 = List(Set(1,2,3), List(1,5,6), Map('a'->"x",'b'->"y"))
l2.flatMap(x=>x.toSet)
res3: List[Any] = List(1, 2, 3, 1, 5, 6, (a,x), (b,y))

val s1 = "hello world"
s1.flatMap(x=>Map(x->x.toString)) 

我们在上面注意到s1.flatten没有工作但是s1.flatMap没有。这是因为,在s1.flatMap中,我们将String(字符)的元素转换为集合的Map。因此,字符串被转换为地图集合(地图(' h' - >" h"),地图(' e' - >&# 34; e"),地图(' l' - >" l"),地图(' l' - >" l&# 34;),地图(' o' - >" o")....)这样flatten现在可以工作。请注意,创建的地图不是地图(' h' - >" h",' e' - >" e",& #39; L' - >" L" ......)

2 个答案:

答案 0 :(得分:1)

查看flatten的完整签名:

def flatten[B](implicit asTraversable: (A) ⇒ GenTraversableOnce[B]): List[B]

如您所见,flatten采用隐式参数。该参数提供了如何展平给定集合类型的规则。如果编译器无法在范围内找到隐式,则可以显式提供。

只要您提供规则,

flatten几乎可以展平任何事情。

答案 1 :(得分:0)

Flatmap基本上是一个地图操作,后面是一个展平