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

时间:2017-09-18 00:52:43

标签: javascript json kotlin kotlin-js-interop

我的示例代码如下:

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

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

2 个答案:

答案 0 :(得分: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语言的一部分,它只是本地浏览器对象的typed definition,称为JSON。 HashMap不是一个空的JavaScript对象,它允许使用任何类型的对象作为键,它暴露了类似Java的Map API,这在JavaScript对象中是不可用的。因此,HashMap不适合您的工作。有几种解决方案:

  1. 您可以等到我们发布Kotlin多平台锯齿,请参阅the corresponding discussion。此API能够理解Kotlin clases并将它们正确地转换为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)
    }
    

答案 1 :(得分:1)

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

  1. 假设您有一个填充的地图
  2. 创建一个空的js对象(对我来说似乎很客气,但这是JS的Kotlin)
  3. 迭代地图的“ toList”方法,该方法可提供配对
  4. 将每对插入js对象
  5. 抓取js JSON API
  6. 并调用“ stringify”以提供您的js对象。记住最后要“ toString”

    d$newcodes <- apply(d, 1, function(x) paste(sort(x), collapse = ""))