Map.mapを使用して、マップをタプルのリストに変換しようとしました。ただし、これは失敗します。私は次の実験をしました:
val m = Map(("a" -> 1), ("b" -> 2))
//> m : scala.collection.immutable.Map[String,Int] = Map(a -> 1, b -> 2)
val r1 = m.map{ case (k,v) => v} //> r1 : scala.collection.immutable.Iterable[Int] = List(1, 2)
def toTuple[A,B](a:A,b:B) = (a,b) //> toTuple: [A, B](a: A, b: B)(A, B)
//val r2: List[Tuple2[_,_]] = m.map(e => (e._1,e._2))
val r3 = m.map(e => toTuple(e._1,e._2)) //> r3 : scala.collection.immutable.Map[String,Int] = Map(a -> 1, b -> 2)
val r4 = m.toSeq //> r4 : Seq[(String, Int)] = ArrayBuffer((a,1), (b,2))
リストは単一の要素(r1)に対して生成されますが、マップはタプル(r3)に対して生成されることに注意してください。タイプを強制することもできませんでした(r2)。 Seqへの明示的な呼び出しのみがそれを行いました(r4)だから私の質問は、なぜ/どうやってMap.mapがリストではなく新しいMapを「自動的に」作成するのですか?実際、戻り値の型はどのように決定されますか(Seq、Listなど)
Map
はすでにタプルのコレクションです。
_scala> "b" -> 2
res0: (String, Int) = (b,2) // Implicitly converted to a Tuple
_
Map
をマッピングするときは、それに含まれる(キー、値)のペアをマッピングします。キーを取り除き、値のみを保持するため、これは機能しません。つまり、あなたが持っているのはMap
ではなく、コレクション階層の1つまたは2つ上のステップ、Iterable
です。
_val r1 = m.map{ case (k,v) => v}
_
_Map[A, B]
_はList[(A, B)]
ではないため、型を強制できません。これはm.map(identity)
と同等です。タプルアクセサーを使用してe
にアクセスしていることに注意してください。
_val r2: List[Tuple2[_,_]] = m.map(e => (e._1,e._2))
val r3 = m.map(e => toTuple(e._1,e._2))
_
ここでは、Seq
はList
よりも一般化されています。
_val r4 = m.toSeq
_
@EndeNeuで述べられている簡単な解決策は、toList
を使用することです。コレクションをmap
すると、可能であれば元のコレクションタイプを返す必要があります。そのため、Map
をマッピングすると、_r1
_で基本となる構造体がMap
(キーを完全に削除するような)にならない限り、別のMap
が返されます。