Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
365 views
in Technique[技术] by (71.8m points)

flatten and flatMap in scala

I'll like to check if I have understood flatten and flatMap functions correctly.

1) Am I correct that flatten works only when a collection constitutes of other collections. Eg flatten would work on following lists

//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"))

But flatten will not work on following

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")

'flatten' method would create a new list consisting of all elements by removing the hierarchy. Thus it sort of 'flattens' the collection and brings all elements at the same level.

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' first applies a method to elements of a list and then flattens the list. As we noticed above, the flatten method works if lists have a hierarchy (contain other collections). Thus it is important that the method we apply to the elements returns a collection otherwise flatMap will not work

//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)) 

We notice above that s1.flatten didn't work but s1.flatMap did. This is because, in s1.flatMap, we convert elements of a String (characters) into a Map which is a collection. Thus the string got converted into a collection of Maps like (Map('h'->"h"), Map('e'->"e"), Map('l'->"l"),Map ('l'->"l"),Map('o'->"o")....) Thus flatten will work now. Note that the Map created is not Map('h'->"h", 'e'->"e", 'l'->"l",....).

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Take a look at the full signature for flatten:

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

As you can see, flatten takes an implicit parameter. That parameter provides the rules for how to flatten the given collection types. If the compiler can't find an implicit in scope then it can be provided explicitly.

flatten can flatten almost anything as long as you provide the rules to do so.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...