gpt4 book ai didi

scala - 如何更新嵌套的不可变映射

转载 作者:行者123 更新时间:2023-12-02 06:52:50 25 4
gpt4 key购买 nike

我正在尝试找到一种更简洁的方法来更新 Scala 中的嵌套不可变结构。我想我正在 Clojure 中寻找类似于 assoc-in 的东西。我不确定这有多少类型因素。

例如,在 Clojure 中,要更新嵌套 map 的“城市”属性,我会这样做:

> (def person {:name "john", :dob "1990-01-01", :home-address {:city "norfolk", :state "VA"}})
#'user/person
> (assoc-in person [:home-address :city] "richmond")
{:name "john", :dob "1990-01-01", :home-address {:state "VA", :city "richmond"}}

我在 Scala 中有哪些选择?

val person = Map("name" -> "john", "dob" -> "1990-01-01", 
"home-address" -> Map("city" -> "norfolk", "state" -> "VA"))

最佳答案

如另一个答案所示,您可以利用 case classes 来获得更清晰的类型化数据对象。但如果您需要的只是更新 map :

val m = Map("A" -> 1, "B" -> 2)
val m2 = m + ("A" -> 3)

结果(在工作表中):

m: scala.collection.immutable.Map[String,Int] = Map(A -> 1, B -> 2)
m2: scala.collection.immutable.Map[String,Int] = Map(A -> 3, B -> 2)

Map 上的 + 运算符将添加新的键值对,如果它已经存在则覆盖。但值得注意的是,由于原始值是 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。 .

关于scala - 如何更新嵌套的不可变映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39278936/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com