Do not mix side effects with clean code. Therefore, I did not solve your randomization problem.
Secondly, I would recommend not to delete the "election" field so that everything is simple. Delete this field later when you want.
Third, separate the stages of production and transformation for simplicity. Here you can use the case class to do most of the work.
I am sure that this may not be an idiomatic Circe solution, but a good Scala:
import io.circe._, io.circe.generic.auto._, io.circe.parser._, io.circe.syntax._ object ChooserApp extends App { val input = """{ "choices" : [ { "name" : "A" }, { "name" : "B" }, { "name" : "C" }, { "name" : "D" } ], "domain" : "Quizz", "level" : "Test", "mandatory": true }""" val expected = """{ "choices" : [ { "name" : "A" }, { "name" : "B" }, { "name" : "C" }, { "name" : "D" } ], "value":"B", "domain" : "Quizz", "level" : "Test", "mandatory": true }""" case class ForJson(j: Json) { def choices: List[String] = { j.asObject .toList .flatMap(_ ("choices")) .flatMap(_.asArray) .flatten .flatMap(_.asObject) .flatMap(_ ("name")) .flatMap(_.asString) } def chosen(a: String): Json = { j.asObject .map(_.add("value", Json.fromString(a))) .map(Json.fromJsonObject) .getOrElse(j) } } val expectedList = List("A", "B", "C", "D") val gotList = ForJson(parse(input).toOption.get).choices assert(gotList == expectedList, s"Expected $expectedList, got $gotList") val expectedJson = parse(expected).toOption.get val gotJson = ForJson(parse(input).toOption.get).chosen("B") assert(gotJson == expectedJson, s"Expected $expectedJson, got $gotJson") }
source share