4

私は Map[String,Seq[String]] を持っていて、基本的にそれを Map[String,String] に変換したいと思っています。シーケンスには値が 1 つしかないことがわかっているからです。

4

4 に答える 4

4

他の誰かがすでに言及mapValuesしましたが、私があなただったら、次のようにします。

scala> val m = Map(1 -> Seq(1), 2 -> Seq(2))
m: scala.collection.immutable.Map[Int,Seq[Int]] = Map(1 -> List(1), 2 -> List(2))

scala> m.map { case (k,Seq(v)) => (k,v) }
res0: scala.collection.immutable.Map[Int,Int] = Map(1 -> 1, 2 -> 2)

2 つの理由:

  1. このmapValuesメソッドは、結果の Map のビューを生成します。つまり、要素にアクセスするたびに関数が再計算されます。各要素に 1 回だけアクセスする予定がある場合、またはそれらのごく一部のみにアクセスする予定がある場合を除き、その再計算を実行する必要はありません。

  2. case with を使用すると、関数が要素を 1 つだけ(k,Seq(v))含まない Seq を検出した場合に例外がスローされることが保証されます。orを使用すると、要素がゼロの場合は例外がスローされますが、要素が複数ある場合はエラーが発生しません。これにより、後でエラーが発生せずに欠落したときに不可解なバグが発生する可能性があります。_(0)_.head

于 2012-09-18T17:53:23.863 に答える
3

使用できますmapValues()

scala> Map("a" -> Seq("aaa"), "b" -> Seq("bbb"))
res0: scala.collection.immutable.Map[java.lang.String,Seq[java.lang.String]] = M
ap(a -> List(aaa), b -> List(bbb))

scala> res0.mapValues(_(0))
res1: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(a
-> aaa, b -> bbb)
于 2012-09-18T17:36:51.910 に答える
0

私は次のことをすることでそれを得たと思います:

mymap.flatMap(x => Map(x._1 -> x._2.head))
于 2012-09-18T17:36:11.127 に答える
0

さらに別の提案:

m mapValues { _.mkString }

これは、Seq に複数の要素があるかどうかにとらわれず、すべての文字列を連結するだけです。各値の再計算が心配な場合は、前もって実行できます。

(m mapValues { _.mkString }).view.force
于 2012-09-18T23:07:07.207 に答える