在circe中使用状态转换JSON
注:为了子孙后代的利益,我将这个问题从头到尾复制过来 假设我们要翻译此JSON文档:在circe中使用状态转换JSON,json,scala,circe,Json,Scala,Circe,注:为了子孙后代的利益,我将这个问题从头到尾复制过来 假设我们要翻译此JSON文档: { "places": [{ "id": "dadcc0d9-0615-4e46-9df4-2619f49930a0" }, { "id": "21d02f4b-7e88-47d7-bf2b-48e50761b6c3" }], "transitions": [{ "id": "10a3aee5-541b-4d04-bb45-cb1dbbfe2128", "star
{
"places": [{
"id": "dadcc0d9-0615-4e46-9df4-2619f49930a0"
}, {
"id": "21d02f4b-7e88-47d7-bf2b-48e50761b6c3"
}],
"transitions": [{
"id": "10a3aee5-541b-4d04-bb45-cb1dbbfe2128",
"startPlaceId": "dadcc0d9-0615-4e46-9df4-2619f49930a0",
"endPlaceId": "21d02f4b-7e88-47d7-bf2b-48e50761b6c3"
}],
"routes": [{
"id": "6ded1763-86c0-44ce-b94b-f05934976a3b",
"transitionId": "10a3aee5-541b-4d04-bb45-cb1dbbfe2128"
}]
}
为此:
{
"places": [{
"id": "1"
}, {
"id": "2"
}],
"transitions": [{
"id": "3",
"startPlaceId": "ref:1",
"endPlaceId": "ref:2"
}],
"routes": [{
"id": "4",
"transitionId": "ref:3"
}]
}
也就是说,我们希望用一个简单的递增数字标识符替换每个id
中的UUID,并用对新标识符的引用替换对每个UUID的所有引用
我们如何使用?使用(circe依赖的库)中的状态单变量转换器可以相对直接地实现这一点: 然后:
import io.circe.literal._
val doc: Json = json"""
{
"places": [{
"id": "dadcc0d9-0615-4e46-9df4-2619f49930a0"
}, {
"id": "21d02f4b-7e88-47d7-bf2b-48e50761b6c3"
}],
"transitions": [{
"id": "10a3aee5-541b-4d04-bb45-cb1dbbfe2128",
"startPlaceId": "dadcc0d9-0615-4e46-9df4-2619f49930a0",
"endPlaceId": "21d02f4b-7e88-47d7-bf2b-48e50761b6c3"
}],
"routes": [{
"id": "6ded1763-86c0-44ce-b94b-f05934976a3b",
"transitionId": "10a3aee5-541b-4d04-bb45-cb1dbbfe2128"
}]
}
"""
最后:
scala> import cats.std.long._
import cats.std.long._
scala> import cats.std.map._
import cats.std.map._
scala> update(doc).runEmptyA
res0: Option[io.circe.Json] =
Some({
"places" : [
{
"id" : "1"
},
{
"id" : "2"
}
],
"transitions" : [
{
"id" : "3",
"startPlaceId" : "ref:1",
"endPlaceId" : "ref:2"
}
],
"routes" : [
{
"id" : "4",
"transitionId" : "ref:3"
}
]
})
如果任何
id
字段不是合法的UUID,或者如果任何其他字段包含对未知UUID的引用,则计算将失败,结果为None
。可以根据需要对该行为进行一些改进,如果您需要有关错误发生位置的更具体信息,可以调整实现以使用游标而不是JSON值(但这会变得更复杂一些)。可以ids.updated(uuid,next)
替换为ids+(uuid->next)
?@Łukasz是的,但是我发现更新后的更清晰了一些,因为它不需要显式地创建元组,而且我们总是只添加一个键值对。好的,谢谢您的解释。我觉得这有点混乱,因为这也允许替换现有值,但这永远不会发生,而且您的意图是插入一个新元素,但现在我也看到了您的方法的优点。但是+
也替换了现有值。:)同意,虽然这是一个品味上的细微差异问题,而且我不认为+
或更新的
明显更好。该死,我学到的另一件事,我认为+不会做更新,但如果我想一想,这是完全有道理的:)
scala> import cats.std.long._
import cats.std.long._
scala> import cats.std.map._
import cats.std.map._
scala> update(doc).runEmptyA
res0: Option[io.circe.Json] =
Some({
"places" : [
{
"id" : "1"
},
{
"id" : "2"
}
],
"transitions" : [
{
"id" : "3",
"startPlaceId" : "ref:1",
"endPlaceId" : "ref:2"
}
],
"routes" : [
{
"id" : "4",
"transitionId" : "ref:3"
}
]
})