Согласно документу scala, существует две версии flatMap
function: Одна возвращает новую итерируемую коллекцию, а другая возвращает новую карту. Тип результирующей коллекции определяется статическим типом итерируемой коллекции, что иногда может приводить к неожиданным результатам.
Проще говоря, если функция, которую мы предоставили в аргументе flatMap
, возвращает один элемент, нам будет возвращена итерируемая коллекция. С другой стороны, если функция в аргументе flatMap
возвращает коллекцию, нам будет возвращена новая Карта.
Например, вот ваша входная переменная:
scala> val numMap = Map(1 -> List(2) , 3 -> List(2,4))
Если мы вернем только один элемент из аргумента функции в flatMap
, мы получим List
scala> numMap.flatMap{case(k,v) => v}
res0: List(2, 2, 4)
или (другой способ вернуть один элемент)
scala> numMap.flatMap{case(k,v) => v.map(e => e)}
res1: List(2, 2, 4)
Однако, если мы вернем коллекцию из функции в flatMap
, мы получим Map
. Здесь мы возвращаем кортеж (<element of list>, <key>)
scala> numMap.flatMap{case(k,v) => v.map(e => (e,k))}
res2: Map(2 -> 3, 4 -> 3)
Если мы хотим вернуть коллекцию из аргумента функции flatMap
, мы можем использовать case class
и получить List
:
scala> case class MyCollection(a: Int, b: Int)
scala> numMap.flatMap{case(k,v) => v.map(e => MyCollection(e,k))}
res4: List(MyCollection(2,1), MyCollection(2,3), MyCollection(4,3))
person
Ayush Vatsyayan
schedule
14.08.2019
flatMap
для Map, один из них вернет другой Map, если возвращаемый тип функции представляет собой другой набор кортежей. Есть две альтернативы, одна из которых заключается в принудительной перегрузке другой через параметры типаnumMap.flatMap[(Int, Int)] { ... }
, однако эта будет возвращать Iterable[(Int, Int)] вместо List. Другой альтернативой является использование итератора,numMap.iterator.flatMap { ... }.toList
. - person Luis Miguel Mejía Suárez   schedule 14.08.2019flatMap
над монадой должна возвращать другую монаду того же типа, поэтому настоящий вопрос заключается в том, почемуMap.flatMap
не возвращает еще однуMap
! - person Tim   schedule 14.08.2019scala> Map(2 -> 3, 4 -> 3).flatMap { case (k,v) => List(k,v) } res29: scala.collection.immutable.Iterable[Int] = List(2, 3, 4, 3)
- person Benny   schedule 14.08.2019class
. statictype
переменной Iterable. Для компилятора существует толькоtypes
, вы не можете безопасно использовать его как List, только как Iterable. - person Luis Miguel Mejía Suárez   schedule 14.08.2019List
, однако я не знал, что рантайм-класс может отличаться от статического типа. Где я могу найти дополнительную информацию об этом? - person Benny   schedule 17.08.2019List
является подтипомIterable
. Таким образом, реализация может выбрать его, не нарушая контракт. Вы можете сделать это в любом месте, это принцип подтипирования. Кроме того, вас может заинтересовать этот блог это объясняет разницу между временем компиляции типами и временем выполнения классами. - person Luis Miguel Mejía Suárez   schedule 17.08.2019