Получение нулевых значений из json с помощью Circe-optics

У меня есть json, который выглядит так:

{
    "cards": [
        {
            "card_id":"1234567890",
            "card_status":"active",
            "card_expiration":{
                "formatted":"01/20"
            },
            "debit":{
                "masked_debit_card_number":"1111 **** **** 1111",
            }
        },
        {
            "card_id":"1234567891",
            "card_status":"active",
            "card_expiration":null,
            "debit":{
                "masked_debit_card_number":"2222 **** **** 2222",
            }
        }
    ]
}

Я пытаюсь вернуть все card_expiration значения полей с помощью этой функции:

def getExpirations(json: Json) =
    root
        .cards
        .each
        .filter(root.card_status.string.exist(_ == "active"))
        .card_expiration
        .selectDynamic("formatted")
        .string
        .getAll(json)

Дело в том, что приведенное выше выражение возвращает только 1 результат - для первой карты, но мне действительно нужно получить что-то вроде List(Some("01/20"), None)! Что я могу сделать в этой ситуации?

1 ответ

Решение

Проблема в том, что к тому времени, когда вы сделаете formatted шаг вы больше не соответствуете nullистечение срока. Вы можете сделать что-то вроде этого:

import io.circe.Json, io.circe.optics.JsonPath.root

def getExpirations(json: Json) =
  root
    .cards
    .each
    .filter(root.card_status.string.exist(_ == "active"))
    .card_expiration
    .as[Option[Map[String, String]]]
    .getAll(json)

Или:

import io.circe.Json, io.circe.generic.auto._, io.circe.optics.JsonPath.root

case class Expiration(formatted: String)

def getExpirations(json: Json) =
  root
    .cards
    .each
    .filter(root.card_status.string.exist(_ == "active"))
    .card_expiration
    .as[Option[Expiration]]
    .getAll(json)

А потом:

scala> getExpirations(io.circe.jawn.parse(doc).right.get)
res0: List[Option[Expiration]] = List(Some(Expiration(01/20)), None)

Без дополнительного контекста, на мой взгляд, неясно, подходит ли этот вариант для круговой оптики. Возможно, вам лучше декодировать в классы case или, возможно, использовать курсоры. Если бы вы могли предоставить больше информации, было бы легче сказать.

Другие вопросы по тегам