Подтвердить что ты не робот

Scala Iterable # map против Iterable # flatMap

В чем разница между функциями map и flatMap от Iterable?

4b9b3361

Ответ 1

Вот довольно хорошее объяснение:

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], а карта принимает тип [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)

Ответ 2

Все это верно, но есть еще одна вещь, которая удобна: flatMap превращает a List[Option[A]] в List[A], при этом любой Option, который сверлит до None, удаляется. Это ключевой концептуальный прорыв для выхода за рамки null.

Ответ 3

Из scaladoc:

  • Карта

Возвращает итеративный результат от применения данной функции f к каждый элемент этого итерабельного.

  • flatMap

Применяет заданную функцию f каждому элементу этого итерабельного, тогда объединяет результаты.

Ответ 4

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

Каждый итератор внутри for будет переведен в "flatMap", кроме последнего, который переводится на "карту". Таким образом, вместо того, чтобы возвращать вложенные коллекции (список массива буфера blah, blah, blah), вы возвращаете плоскую коллекцию. Коллекция, образованная элементами, получаемыми - список целых чисел. В этом случае.