Как удалить нулевые значения в списке объектов с помощью Circe - PullRequest
1 голос
/ 13 февраля 2020

Я пытаюсь закодировать список объектов, используя Circe, что-то похожее на:

val test = Seq(MyObject("hello", None, 1, 2, None)

Я пытаюсь проанализировать это с помощью Circe:

test.asJson

Но при этом создается объект JSON:

[
  {
    name: "hello",
    someVal: null,
    someNum: 1,
    anotherNum: 2,
    anotherVal: null
  }
]

Я пытался запустить asJson с .dropNullValues, но это не похоже получить доступ к нулевым значениям внутри объекта. Есть ли способ отбросить нулевые значения внутри объектов?

Я ожидаю что-то более похожее на это:

[
  {
    name: "hello",
    someNum: 1,
    anotherNum: 2
  }
]

1 Ответ

0 голосов
/ 13 февраля 2020

Вы видите field: null, потому что circe превращается Option[T] в t.asJson на Some[T] и JsonNull на None, а кодировщик класса дел по умолчанию просто помещает все поля в JsonObject. Таким образом, что Circe использует для кодирования семейства запечатанных признаков, он может использовать эти поля null для различения guish классов, таких как

sealed trait Foo
case class Bar(a: Option[String])
case class Baz(a: Option[String], b: Option[String])

Так что, если вы действительно Если вы хотите отбросить эту информацию и нуждаетесь в одностороннем преобразовании с потерей информации, вы можете отобразить результирующее Json, чтобы отбросить все пустые поля с таким кодом:


implicit val fooEnc: Encoder[Foo] = deriveEncoder[Foo].mapJsonObject{jsonObj => jsonObj.filter{case (k,v) => !v.isNull}}

Однако вы должны написать такой Пользовательский код c для любого класса, который вы хотите удалить пустые поля. Чтобы постобработать json, вы можете использовать Fold на результирующем json:

  val json: Json = ???
  json.fold[Json](
    Json.Null,
    Json.fromBoolean,
    {_.asJson},
    {_.asJson},
    {_.asJson},
    {jsonObj => jsonObj.filter{case (k,v) => !v.isNull}.asJson}
  )

или создать собственную папку.

...