flatten и flatMap в scala

Я хотел бы проверить, правильно ли я понял функции 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"))

Но сглаживание не будет работать при следующем

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 создаст новый список, состоящий из всех элементов, удалив иерархию. Таким образом, это как бы «сглаживает» коллекцию и приводит все элементы на один уровень.

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 мы преобразуем элементы строки (символы) в карту, которая является коллекцией. Таким образом, строка была преобразована в набор карт, например (Map('h'->"h"), Map('e'->"e"), Map('l'->"l"),Map ( 'l'->"l"),Map('o'->"o")....) Таким образом, flatten теперь будет работать. Обратите внимание, что созданная Карта не является Картой('h'->"h", 'e'->"e", 'l'->"l",....).


person Manu Chadha    schedule 07.12.2016    source источник
comment
Ну, да ...   -  person Dima    schedule 08.12.2016
comment
А ваш вопрос?   -  person Stefano Bonetti    schedule 08.12.2016
comment
Неявный вопрос: «Правильно ли я понял «flatten» и «flatMap»?   -  person Manu Chadha    schedule 08.12.2016


Ответы (2)


Взгляните на полную подпись для flatten:

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

Как видите, flatten принимает неявный параметр. Этот параметр предоставляет правила выравнивания заданных типов коллекций. Если компилятор не может найти неявное значение в области видимости, его можно указать явно.

flatten может сгладить почти что угодно, если вы предоставите для этого правила.

person jwvh    schedule 07.12.2016

Flatmap — это, по сути, операция с картой, за которой следует сглаживание.

person pedrorijo91    schedule 08.12.2016