The release notes for 0.5.1 say:
ujson.write now takes an optional `sortKeys` flag, if you want the JSON dictionaries to rendered in a standardized order
But that doesn't seem to exist any more. How do I ensure that Object keys are sorted? This is to make it easier to compare versions of a JSON file in a diff tool...
I see ujson.Obj
uses a LinkedHashMap
so it will preserve insertion order. Rather than sorting into a new Obj
when the contents have all been added I could do a two-step process but it's still a bit clunky as it requires a Map
copy:
val sortedMap = mutable.SortedMap[String, ujson.Value]()
addSomeStuffWithUnpredictableKeyOrdering(sortedMap)
val obj = ujson.Obj.from(sortedMap)
What would be nice is if Obj
could be configured to use either mutable.LinkedHashMap
as at present, or mutable.SortedMap
- then you could choose to either preserve insertion order, or have ordering by key.
ujson.Obj
could hold a reference of a mutable.Map[String, ujson.Value]
instead of a mutable.LinkedHashMap[String, ujson.Value]
.mutable.LinkedHashMap[String, ujson.Value]
and you could pass a different type of map by doing:val myMap = mutable.SortedMap[String, ujson.Value]()
val obj = new ujson.Obj(myMap)
@lolgab well, you shouldn't really be depending on map key ordering in the first place I suppose, but you already get that with the current implementation ;-)
I'd settle for being able to specify ordering during write
, again I know you shouldn't do that with JSON but it does make it easier to process with existing diff tools...
visitObject
, and does this:
def visitKeyValue(s: Any): Unit = {
lastNested.visitValue(s.asInstanceOf[T], lastKeyIndex)
}
However, nobody set lastNested
, so it's now null... Should I not use this call, and/or use visitKey first?
"id""
.visitKey(-1)
everywhere before .visitKeyValue
... this seems to solve it :)
case class Thing(myFieldA: Int, myFieldB: String)
object Thing{
implicit val rw: RW[Thing] = macroRW
}
case class Big(i: Int, b: Boolean, str: String, c: Char, t: Thing)
object Big{
implicit val rw: RW[Big] = macroRW
}
object TestClient {
def main(args: Array[String]): Unit = {
read[Thing]("""{"myFieldA":1,"myFieldB":"gg"}""")
}
}
Gives me an error and suggests to import upickle.legacy.read
no implicit argument of type upickle.legacy.Reader[Thing] was found for an implicit parameter of method read in trait Api.
I found: upickle.legacy.given_Reader_T[T](/* missing */summon[deriving.Mirror.Of[T]])
But no implicit values were found that match type deriving.Mirror.Of[T].
https://github.com/objektwerks/scala3.json
. The most recent test uses Scala 3 and uPickle 2.0.0. Has anyone else noticed this performance change?
@ghstrider You can't literally convert Var[List[T]]
into List[Var[T]]
... because the List size inside the Var can change over time, but List
is immutable. Similar to how you can't convert scala.Future[List[T]]
into List[scala.Future[T]]
.
If you have a Var[List[T]]
and want to render a separate input for each T in the Var by giving it something like Var[T]
, you should use the split
operator, something like:
val inputValues: L.Var[List[String]] = ???
div(
...,
children <-- inputValues.signal.map(_.zipWithIndex).split(_._2)((index, _, inputValue: Signal[T]) => {
input(
controlled(
value <-- inputValue,
onInput.mapToValue --> inputValues.updater( /* update string at index `index` here */)
)
)
})
)