I am trying to implement an insert function using the ujson library:
Here is my attempt:
import ujson.{Obj, Value}
import upickle.default._
object Example extends App {
def r = transform(
List(Map(
"a" -> Map("b" -> Obj("c" -> List(1,2,3), "d" -> List(2,4,6))),
"e" -> Map("f" -> Obj("g" -> List(1,2,3)))))
).to(Value)
def insert(j: ujson.Value, k: String, v: ujson.Value): Unit = j match {
case a: ujson.Arr => a.arr.foreach(e => insert(e, k, v))
case o: ujson.Obj =>
if (o.obj.keySet contains k) o.obj(k) = v
else o.obj.values.foreach(e => insert(e, k, v))
case _ => Nil
}
println(r)
insert(r, "b", transform(None).to(Value))
println(r)
}
However, this gives me output that is unchanged:
[{"a":{"b":{"c":[1,2,3],"d":[2,4,6]}},"e":{"f":{"g":[1,2,3]}}}]
[{"a":{"b":{"c":[1,2,3],"d":[2,4,6]}},"e":{"f":{"g":[1,2,3]}}}]
Given that the Value type is mutable, why does this not mutate and update the key, k, with value v for json value object r?
You are creating Value
anew every time you call r
so, every changes you would make to it, are dismissed.
You create one copy when you call println(r)
.
Then you create a separate copy with insert(r, "b", transform(None).to(Value))
, mutate it and dismiss.
Then you are creating third copy with another println(r)
.
If you want to refer to the same object use val
instead of def
.