Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在circe中使用状态转换JSON_Json_Scala_Circe - Fatal编程技术网

在circe中使用状态转换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

注:为了子孙后代的利益,我将这个问题从头到尾复制过来

假设我们要翻译此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"
  }]
}
为此:

{
  "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"
    }
  ]
})