他の回答で示したように、あなたはクリーン取得するcase classes
を活用することができますが、データ・オブジェクトを入力しました。しかし、場合にはあなたが必要なものマップを更新するだけです:
val m = Map("A" -> 1, "B" -> 2)
val m2 = m + ("A" -> 3)
結果(ワークシート):Map
の+
オペレータは、新しいキーと値のペアを追加します
m: scala.collection.immutable.Map[String,Int] = Map(A -> 1, B -> 2)
m2: scala.collection.immutable.Map[String,Int] = Map(A -> 3, B -> 2)
、すでに存在する場合は上書きします。ただし、元の値がval
であるため、元の値を変更できないため、結果に新しいval
を割り当てる必要があります。
、あなたの例では、あなたがこれを手動でやや面倒になりやって、ネストされた値を書き換えているので:これは、いくつかの損失のデータを生成する
val m = Map("A" -> 1, "B" -> Map("X" -> 2, "Y" -> 4))
val m2 = m + ("B" -> Map("X" -> 3))
(ネストY
値が消える):
したがって
m: scala.collection.immutable.Map[String,Any] = Map(A -> 1, B -> Map(X -> 2, Y -> 4))
m2: scala.collection.immutable.Map[String,Any] = Map(A -> 1, B -> Map(X -> 3)) // Note that 'Y' has gone away.
、元の値をコピーし、それをバックに再割り当てすることができ強制:
val m = Map("A" -> 1, "B" -> Map("X" -> 2, "Y" -> 4))
val b = m.get("B") match {
case Some(b: Map[String, Any]) => b + ("X" -> 3) // Will update `X` while keeping other key-value pairs
case None => Map("X" -> 3)
}
val m2 = m + ("B" -> b)
これは「期待」の結果が得られますが、明らかに多くのコードです:要するに
m: scala.collection.immutable.Map[String,Any] = Map(A -> 1, B -> Map(X -> 2, Y -> 4))
b: scala.collection.immutable.Map[String,Any] = Map(X -> 3, Y -> 4)
m2: scala.collection.immutable.Map[String,Any] = Map(A -> 1, B -> Map(X -> 3, Y -> 4))
、任意の不変のデータ構造と、それはあなたが本当にあなたが望むすべての部分をコピーしているときに、「更新」と必要に応じて更新された値を含めます。構造が複雑な場合、これは厄介なものになる可能性があります。したがって、@ 0 ___が与えた、例えば、Monocleの勧告。
特に、 'Map [String、Any]'はScalaでは面白くないでしょう。 – Ryan
@ Ryan:任意のコレクションタイプシグネチャの「Any」の悪いサインが存在していませんか? List [Any]など – Samar
はい、タイプシステムが「Any」を推論しなければならないときは、おそらく間違いを犯したでしょう。 – Ryan