I'm writing a library to convert JSON responses from an API for backwards compatibility reasons. And what I need to do is take in arbitrary JSON, and change certain field names. I'm using scala and argonaut, but I don't see any way in the docs or examples of changing the FIELD names, only the values.
Asked
Active
Viewed 1,215 times
2 Answers
1
I don't know of a particularly nice way to do this, but it's not too awful to write a helper that will replace a field in an object and then use that in a cursor with withObject
:
def renameField(before: JsonField, after: JsonField)(obj: JsonObject) =
obj(before).map(v => (obj - before) + (after, v)).getOrElse(obj)
Parse.parseOption("""{ "a": { "b": { "c": 1 } } }""").flatMap { json =>
(json.hcursor --\ "a").withFocus(_.withObject(renameField("b", "z"))).undo
}
This will return Some({"a":{"z":{"c":1}}})
as expected.

Travis Brown
- 138,631
- 12
- 375
- 680
-
So if I'm reading that correctly, it looks like I have to know the structure of the JSOn beforehand, which I don't necessarily. I just want to rename any fields named "a" to "b" (roughly). I came up with a solution, but it's equally un-nice. – Falmarri Jan 21 '14 at 20:39
1
I ended up folding over the object I need to convert and adding to a map, and then creating a new json object.
val conversionMap = Map("a" -> "b")
Json(
j.objectOrEmpty.toMap.foldLeft(Map.empty[JsonField, Json]) {
case (acc, (key, value)) =>
acc.updated(conversionMap.getOrElse(key, key), j.fieldOrNull(key))
}.toSeq: _*
)

Falmarri
- 47,727
- 41
- 151
- 191