Как извлечь Seq [String] из Option [Seq [Case Class]] - PullRequest
0 голосов
/ 01 декабря 2019

У меня есть JSON, и я анализирую JSON для приведенных ниже классов. Я использую Play JSON для разбора. Ниже приведены мои классы дел

case class Result(id: String, account : Option[Seq[Account],data: Option[Seq[Data]])
case class Account(accountId: Option[String] = None)
case class Data(primaryId: Option[String] = None,
                            accountId: Option[String] = None)

Из класса дел данных мне нужен весь primaryId как Seq [String], который сопоставляет accountId класса дел данных с accountId класса дел Account.

Ниже приведен фрагмент кода, который я пробовал. Я попробовал сделать это двумя способами

Первый способ

primaryIds = data.map(cd =>
            for{
                c <- cd
              if c.relatedAccountId == account.accountId
            }yield c.primaryId.get)))

Второй способ

primaryIds = data.map(_.collect {
                    case s if s.relatedAccountId.equals(account.accountId) & s.primaryId.isDefined => s.primaryId.get

Вот мои вопросы

Это правильно использоватьs.primaryId.get. Что делать, если s.primaryId - Нет? И None.get выдаст исключение. Есть ли лучший способ справиться с этим. Пожалуйста, дайте мне знать

Ответы [ 2 ]

1 голос
/ 02 декабря 2019

Примерно так должно работать:

result.data.map{ cd =>
  cd.filter(c => account.exists(_.accountId == c.accountId))
    .flatMap(_.primaryId.toList)
}.getOrElse(Seq.empty[String])

Option[T] имеет метод toList, который отлично работает, когда вы хотите flatMap с Seq[Option[T]]. Никогда не используйте Option.get. Метод getOrElse возвращает значение по умолчанию (Seq.empty[String]), если опция None.

Кроме того, вам следует изучить упрощение типов, которые вы используете в своих классах. Вместо использования Option[Seq[T]] используйте обычный Seq[T]. Вы можете представить отсутствующее значение пустым списком Seq.empty. Это небольшое изменение будет иметь большое значение, потому что оно упрощает вашу способность работать с вашими данными.

0 голосов
/ 02 декабря 2019

Почти всегда плохая идея использовать .get на Option[_]. Причем в первую очередь вы сравниваете варианты. Это не очень хорошая идея, потому что это может привести к странному результату (None == None => true).

Вместо получения значения accountId вы можете использовать flatMap вот так

primaryIds = data.map(cd =>
        cd.flatMap{
           case Data(maybePrimaryId, Some(accountId)) if currentAccount.accountId.contains(accountId) => maybePrimaryId
          case _ => None
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...