scala Iterable#map срещу Iterable#flatMap

Каква е разликата между функциите map и flatMap на Iterable?


person Landon Kuhn    schedule 29.06.2009    source източник


Отговори (5)


Ето едно доста добро обяснение:

http://www.codecommit.com/blog/scala/scala-collections-for-the-easily-bored-part-2

Използване на списък като пример:

Сигнатурата на картата е:

map [B](f : (A) => B) : List[B]

и flatMap е

flatMap [B](f : (A) => Iterable[B]) : List[B]

Така че flatMap приема тип [A] и връща итерируем тип [B], а map приема тип [A] и връща тип [B]

Това също така ще ви даде представа, че flatmap ще "изравнява" списъците.

val l  = List(List(1,2,3), List(2,3,4))

println(l.map(_.toString)) // changes type from list to string
// prints List(List(1, 2, 3), List(2, 3, 4))

println(l.flatMap(x => x)) // "changes" type list to iterable
// prints List(1, 2, 3, 2, 3, 4)
person agilefall    schedule 29.06.2009
comment
Интересно е да се отбележи, че l flatMap { x => x } е точно еквивалентно на l.flatten според монадичните аксиоми. FlatMap е еквивалентът на Scala на монадичната bind операция (››= в Haskell). Смятам, че е най-полезно за монади без колекции като Option. Когато е във връзка с колекции, той е най-полезен за внедряване на вложени цикли на картата, връщайки колекция като резултат. - person Daniel Spiewak; 30.06.2009
comment
Добре казано. С верижното свързване на Options е много по-добре да се работи, отколкото с куп изрази като if(x != null и x.foo != null). blog.lostlake.org/index.php?/archives/ обсъжда това подробно - person agilefall; 30.06.2009
comment
println(l.flatMap(x =› x)) това вече не работи и flatMap трябва да се използва така: aperiodic.net/phil/scala/s-99/p07.scala - person Olivier Girardot; 18.08.2011

Всичко по-горе е вярно, но има още едно полезно нещо: flatMap превръща List[Option[A]] в List[A], като всяко Option, което се разбива до None, се премахва. Това е ключов концептуален пробив за излизане отвъд използването на null.

person kikibobo    schedule 29.06.2009
comment
О, това е още един хубав трик с Option, за който никога не съм се замислял. Току-що имах метод, който върна списък от 1 или повече неща, никога не видях метода Option.toList: List( Some( foo ), None, Some( bar ) ).flatMap( _.toList) - person Tristan Juricek; 01.07.2009
comment
Или може би още по-добре, използвайте Option.toIterator с метода на Tristan, така че да не обикаляте целия списък, докато не е необходимо. - person jkschneider; 06.06.2014

От scaladoc:

  • карта

Връща итерируемия резултат от прилагането на дадената функция f към всеки елемент от този итерируем.

  • плоска карта

Прилага дадената функция f към всеки елемент от този итерируем, след което обединява резултатите.

person skaffman    schedule 29.06.2009
comment
Търся малко повече анализ/обяснение. - person Landon Kuhn; 29.06.2009
comment
Добре, променете въпроса си, за да бъде по-конкретен. Кажете какво вече знаете и какво имате нужда от изясняване. - person skaffman; 29.06.2009
comment
Повече ми хареса твоят остър коментар. - person Landon Kuhn; 30.06.2009
comment
Аз също, но реших, че дискретността е по-добрата част от доблестта :) - person skaffman; 30.06.2009

lines.map(line => line split "\\W+") // will return a list of arrays of words
lines.flatMap(line => line split "\\W+") // will return a list of words

Можете да видите това по-добре в за разбиране:

for {line <- lines
     word <- line split "\\W+"}
yield word.length

това се превежда в:

lines.flatMap(line => line.split("\\W+").map(word => word.length))

Всеки итератор вътре за ще бъде преведен в "flatMap", с изключение на последния, който се превежда в "карта". По този начин, вместо да връщате вложени колекции (списък от масив от буфер от бла, бла, бла), вие връщате плоска колекция. Колекция, образувана от елементите, които се предават -- в този случай списък с цели числа.

person Daniel C. Sobral    schedule 29.06.2009

Вижте тук: http://www.codecommit.com/blog/scala/scala-collections-for-the-easily-bored-part-2

„Търсене на flatMap“ – там има наистина добро обяснение. (По принцип това е комбинация от "изравняване" и "карта" -- функции от други езици).

person Community    schedule 29.06.2009