如何在 kotlin JS 中通过 JSON.stringify 将 Map 序列化为 JSON 字符串?

新手上路,请多包涵

我的示例代码如下:

 fun main(args: Array<String>) {
    val testData = mapOf<String, Any>(
        "name" to "albert",
        "age" to 26,
        "work" to listOf("1", "2", "3")
    )

    var value = JSON.stringify(testData, { _, value -> value.toString() }, 2)

    println(value)
}

结果是 "{name=albert, age=26, work=[1, 2, 3]}" 。似乎它错过了属性名称和字符串值周围的所有双引号。

我正在使用 KotlinJS 而不是 Kotlin

那么,如何解决这个问题呢?

原文由 Albert Gao 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 589
2 个回答

实际上,您不会得到 JSON.stringify 的结果。相反,您会得到 kotlin.collections.HashMap.toString 的结果。原因如下:您将 lambda 作为第二个参数传递: { _, value -> value.toString() } 。这会将您的整个地图转换为字符串,使用 toString() 函数。并且 HashMap.toString 函数被定义为生成这样的字符串,它 不是 JSON 字符串。您应该在没有第二个和第三个参数的情况下使用 JSON.stringify 。但是,这也不会起作用,产生 Uncaught TypeError: Converting circular structure to JSON 错误。原因如下: JSON.stringify 不是 Kotlin 语言的一部分,它只是本地浏览器对象的 类型化定义,称为 JSON。 HashMap 不是一个空的 JavaScript 对象,它允许使用任何类型的对象作为键,它公开了类 Java Map API,这在 JavaScript 对象中是不可用的。所以, HashMap 不适合你在做什么。有几种解决方案:

  1. 您可以等到我们发布 Kotlin 多平台序列化,请参阅 相应的讨论。此 API 能够理解 Kotlin 类并将它们正确转换为 JSON。

  2. 不要使用 Kotlin 映射和列表,使用原生 JavaScript 实体,如 json 和纯数组。您的示例可以按以下方式重写:

导入 kotlin.js.json

    fun main(args: Array<String>) {
       val testData = json(
           "name" to "albert",
           "age" to 26,
           "work" to arrayOf("1", "2", "3")
       )

       var value = JSON.stringify(testData)

       println(value)
   }

原文由 Alexey Andreev 发布,翻译遵循 CC BY-SA 3.0 许可协议

这个答案是在上一个被接受的答案之后几年出现的,但是我(Kotlin 的新手)遇到了同样的问题,并想出了一个很好的方法来实现这一点。

  1. 假设您有一个填充的地图
  2. 创建一个空的 js 对象(对我来说似乎很老套,但这是 JS 的 Kotlin)
  3. 遍历地图的“toList”方法,它提供了一对
  4. 将每一对插入js对象
  5. 获取 js JSON api
  6. 并调用提供您的 js 对象的“stringify”。记住最后要“toString”
    val data: Map<String, Any?> = mapOf() // 1
   val export = js("{}") // 2
   for (pair: Pair<String, Any?> in data.toList()) { // 3
       export[pair.first] = pair.second // 4
   }
   val jsoner = js("JSON") // 5
   return jsoner.stringify(export).toString() // 6

原文由 jabgibson 发布,翻译遵循 CC BY-SA 4.0 许可协议

推荐问题