解析 Scala.js 中数据库行的 JSON 表示

Parsing the JSON representation of database rows in Scala.js

我正在尝试 scala.js,并希望使用从我的 Postgres 数据库中以 json 格式提取的简单行数据。

这里是 json 类型的人为示例我想解析成一些强类型的 scala 集合,需要注意的特征是有 n 行,各种列类型包括一个数组只是为了覆盖可能是现实生活中的场景,不用担心 SQL 创建内联 table 以从中提取 JSON,为了完整起见,我将其包括在内,它是对 [= scala.js 中的 28=] 给我带来了问题

with inline_t as (  
select * from (values('One',1,True,ARRAY[1],1.0),
                     ('Six',6,False,ARRAY[1,2,3,6],2.4494),
                     ('Eight',8,False,ARRAY[1,2,4,8],2.8284)) as v (as_str,as_int,is_odd,factors,sroot))
select json_agg(t) from inline_t t;

 [{"as_str":"One","as_int":1,"is_odd":true,"factors":[1],"sroot":1.0}, 
 {"as_str":"Six","as_int":6,"is_odd":false,"factors":[1,2,3,6],"sroot":2.4494}, 
 {"as_str":"Eight","as_int":8,"is_odd":false,"factors":[1,2,4,8],"sroot":2.8284}]

我认为使用 upickle 或 prickle 之类的东西应该相当容易,如这里所暗示的: 但我找不到代码示例,而且我的速度不够快用 Scala 或 Scala.js 自己解决。如果有人可以 post 一些工作代码来展示如何实现上述目标,我将不胜感激

编辑 这是我尝试过的那种事情,但我并没有走得太远

val jsparsed = scala.scalajs.js.JSON.parse(jsonStr3)

val jsp1 = jsparsed.selectDynamic("1")

val items = jsp1.map{ (item: js.Dynamic) =>
  (item.as_str, item.as_int, item.is_odd, item.factors, item.sroot)
  .asInstanceOf[js.Array[(String, Int, Boolean, Array[Int], Double)]].toSeq
}
println(items._1)

因此,您处于实际想要操纵 JSON 值的情况。由于您不是 serializing/deserializing 端到端的 Scala 值,因此像 uPickle 或 Prickle 这样的序列化库对您帮助不大。

您可以查看跨平台 JSON 操作库,例如 circe。这将为您带来根本不需要 "deal with JavaScript data structures" 的优势。相反,该库将解析您的 JSON 并将其公开为 Scala 数据结构。如果您希望您的 代码也进行交叉编译,这可能是最佳选择。

如果您只编写 Scala.js 代码,并且想要更轻量级的版本(无依赖性),我建议为您的 JSON "schema" 声明类型,然后使用那些以更安全的方式执行转换的类型:

import scala.scalajs.js
import scala.scalajs.js.annotation._

// type of {"as_str":"Six","as_int":6,"is_odd":false,"factors":[1,2,3,6],"sroot":2.4494}
@ScalaJSDefined
trait Row extends js.Object {
  val as_str: String
  val as_int: Int
  val is_odd: Boolean
  val factors: js.Array[Int]
  val sroot: Double
}

type Rows = js.Array[Row]

val rows = js.JSON.parse(jsonStr3).asInstanceOf[Rows]

val items = (for (row <- rows) yield {
  import row._
  (as_str, as_int, is_odd, factors.toArray, sroot)
}).toSeq