Scala получить значение JSON в конкретном типе данных на объекте карты - PullRequest
0 голосов
/ 17 ноября 2018

Используя библиотеку jackson Я читаю данные json из файла (каждая строка файла является объектом JSON) и анализирую их для объекта карты String и Any . Моя цель - сохранить указанные ключи (идентификатор и текст) в коллекцию.

val input = scala.io.Source.fromFile("data.json").getLines()
val mapper = new ObjectMapper() with DefaultScalaModule
val data_collection = mutable.HashMap.empty[Int, String]

for (i <- input){
      val parsedJson = mapper.readValue[Map[String, Any]](i)
      data_collection.put(
        parsedJson.get("id"),
        parsedJson.get("text")
      )

Но поскольку значения на карте parsedJson имеют тип Любой , получая некоторые ключи, такие как id и text , возвращается Некоторые (значение) не только значение с соответствующим типом. Я ожидаю, что значения для ключа id будут целочисленными, а значения для text будут строковыми. Запустив код я получил ошибку:

Error:(31, 23) type mismatch;
 found   : Option[Any]
 required: Int
        parsedJson.get("id"),

Вот пример данных JSON в файле:

{"text": "Hello How are you", "id": 1}

Возможно ли в Scala анализировать значения идентификатора в Int и текстовые значения в String или, по крайней мере, преобразовывать Some (значение) в значение с типом Int или String?

Ответы [ 2 ]

0 голосов
/ 17 ноября 2018

Если вы хотите получить простое значение из Map вместо Option , вы можете использовать метод () (apply) - однако он выдаст исключение, если ключне найден.

Во-вторых, система типов Scala является статической, а не динамической, если у вас есть Any и все, она не изменится на Int или String во время выполнения, и компилятор выйдет из строя- Тем не менее, вы можете привести их, используя метод asInstanceOf[T], но опять же, если тип не может быть приведен к целевому типу, он выдаст исключение.

Обратите внимание, что даже если вы можете заставить свой код работатьс этими трюками этот код не будет таким, как вы ожидаете в Scala.Существуют способы сделать код более безопасным с точки зрения типов (например, сопоставление с образцом) , но разбор Json с типом безопасных с точки зрения типов объектов является старой проблемой, я уверен, что Джексон предоставляет способ разбора json на case case , представляющий ваши данные.Если нет, взгляните на circe .

0 голосов
/ 17 ноября 2018

Попробуйте следующий код:

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import 
 com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper

val input = scala.io.Source.fromFile("data.json").getLines() 
val mapper = new ObjectMapper() with ScalaObjectMapper
mapper.registerModule(DefaultScalaModule)
val obj = mapper.readValue[Map[String, Any]](input)
val data_collection = mutable.HashMap.empty[Int, String]
for (i <- c) {
data_collection.put(
  obj.get("id").fold(0)(_.toString.toInt),
  obj.get("text").fold("")(_.toString)
 )
 }
println(data_collection) // Map(1 -> Hello How are you)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...