json4s ValueError: Shape must be rank 2 but is rank 1 for 'in_top_k/InTopKV2' (op: 'InTopKV2') with input shapes: [30], [30], [].
JsonAST基于extract
和DefaultFormats
中定义的每个类型的规则。
有时我想进行跨场提取。例如,给定一个json字符串CustomSerializer
,我想将{"a": 1, "b": 2}
的值设置为b
。我可以的:
a+b
但是,如果import org.json4s._
import org.json4s.native.JsonMethods._
import org.json4s.JsonAST._
case class A(a: Int, b: Int)
case object ACustomSerializer extends CustomSerializer[A](
format =>
({
case jo: JObject =>
val a = (jo \ "a").extract[Int]
val b = (jo \ "b").extract[Int] + a
A(a, b)
}, Map())
)
implicit val formats = DefaultFormats + ACustomSerializer
parse("""{"a": 1, "b": 2}""").extract[A] // A(1,3)
还有许多其他字段,则很难为所有这些字段编写规则。
case class A
如果我们不想为字段case class A(a: Int, b: Int, c: Int, d: Int)
case object ACustomSerializer extends CustomSerializer[A](
format =>
({
case jo: JObject =>
val a = (jo \ "a").extract[Int]
val b = (jo \ "b").extract[Int] + a
val c = ...
val d = ...
A(a, b, c, d)
}, Map())
)
进行“跨字段提取”,则可以由DefaultFormats
或其他CustomSerializer
处理它们。如果案例类实际上很大,情况会变得更糟。
有没有一种方法可以只为特殊字段编写规则,而其余部分由b
或DefaultFormats
处理?
答案 0 :(得分:2)
通常,最好按原样解析数据,然后再处理(以维护separation of concerns)。
在这种情况下,它看起来像这样:
val a = parse("""{"a": 1, "b": 2}""").extract[A] // A(1,2)
a.copy(b = a.a + a.b) // A(1,3)
在更复杂的情况下,处理后的数据的布局将与解析后的数据不同,因此您将需要第二个case class
来描述原始数据以及将其转换为处理后格式的函数。尽管这看起来很麻烦,但是它将使代码更易于理解并且更易于修改。