Как сериализовать строку Map to JSON через JSON.stringify в 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
Итак, как это решить?
4 ответа
На самом деле, вы не получите результат JSON.stringify
, Вместо этого вы получите результат kotlin.collections.HashMap.toString
, Причина в следующем: вы передаете лямбду в качестве второго параметра: { _, 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
не подходит для того, что вы делаете. Есть несколько решений:
Вы можете подождать, пока мы не опубликуем мультиплатформенную сериализацию Kotlin, смотрите соответствующее обсуждение. Этот API способен понимать предложения Kotlin и правильно преобразовывать их в JSON.
Не используйте карты и списки 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) }
В последних версиях kotlinx-serialization используйтеencodeToDynamic
:
val json = Json.encodeToDynamic(map)
Результатом является динамический объект, содержащий объект JSON. У этого подхода есть некоторые ограничения — например, все ключи карты должны быть примитивами или перечислениями.Long
значения имеют максимальное значение. См. документы для более подробной информации.
Этот ответ приходит через несколько лет после предыдущего принятого ответа, но я (новичок в Kotlin) столкнулся с той же проблемой и нашел хороший способ добиться этого.
- Предположим, у вас есть заполненная карта
- Создайте пустой объект js (мне кажется хакерским, но это Kotlin для JS)
- перебирать метод "toList" вашей карты, который предоставляет Pair
- вставить каждую пару в объект js
- возьмите js JSON api
и вызовите "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
Если вы хотите просто получить действительную строку JSON из Kotlin, вы можете сделать это, используя
kotlinx.serialization.json
:
Json.encodeToString(map)
Если вы хотите красиво упорядочить Kotlin
Map
, который можно отобразить в виде красивого JSON в
<pre>
тег, вы можете сделать:
val jsonString = Json.encodeToString(map) // 1
val jsonObject = JSON.parse<JsonObject>(jsonString) // 2
return JSON.stringify(jsonObject, null, 2) // 3
- Сериализуйте карту в строку JSON, используя сериализацию Kotlin.
- Разобрать строку JSON в объект Javascript
- Довольно упорядочить объект Javascript