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

How to serialize a Map to JSON string via JSON.stringify in kotlin JS?

我的示例代码如下:

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

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

实际上,您不会得到 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 语言的一部分,它只是原生浏览器对象的 typed definition,称为 JSON。 HashMap 不是一个空的 JavaScript 对象,它允许使用任何类型的对象作为键,它公开了 Java-like Map API,这是不可用的在 Java 脚本对象中。所以,HashMap不适合你做的事情。有几种解决方案:

  1. 您可以等到我们发布 Kotlin 多平台序列化,请参阅 the corresponding discussion。 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)
    }
    

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

  1. 假设您有一个填充地图
  2. 创建一个空的 js 对象(对我来说似乎很 hacky,但这是 JS 的 Kotlin)
  3. 遍历地图的 "toList" 方法,该方法提供 Pair
  4. 将每一对插入 js 对象
  5. 抢jsJSONapi
  6. 并调用 "stringify" 提供您的 js 对象。记得最后要"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
    

如果您只想从 Kotlin Map 中检索有效的 JSON 字符串,您可以使用 kotlinx.serialization.json:

Json.encodeToString(map)

如果你想漂亮地字符串化 Kotlin Map,它可以在 <pre> 标签中显示为漂亮的 JSON,你可以这样做:

val jsonString = Json.encodeToString(map)            // 1
val jsonObject = JSON.parse<JsonObject>(jsonString)  // 2
return JSON.stringify(jsonObject, null, 2)           // 3
  1. 使用 Kotlin 序列化将地图序列化为 JSON 字符串
  2. 将 JSON 字符串解析为 Javascript 对象
  3. 很好地字符串化 Javascript 对象