如何从Option [Seq [Case Class]]

时间:2019-12-01 18:41:28

标签: scala playframework

我有一个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与Account案例类的accountId匹配。

以下是我尝试过的代码片段。我尝试了两种方法

第一种方式

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怎么办。而且None.get将引发异常。 有没有更好的方法来解决这个问题。请让我知道

2 个答案:

答案 0 :(得分:1)

类似的事情应该起作用:

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

Option[T]有一个toList方法,当您想将flatMapSeq[Option[T]]一起使用时,效果很好。 切勿使用Option.get。如果选项为getOrElse,则Seq.empty[String]方法将返回默认值(None)。

此外,您应该研究简化案例类中使用的类型。代替使用Option[Seq[T]],而使用常规Seq[T]。您可以用空列表Seq.empty表示缺失值。这个小的更改将带来很大的不同,因为它简化了您处理数据的能力。

答案 1 :(得分:0)

.get上使用Option[_]几乎总是一个坏主意。此外,您可以通过第一种方式比较选项。这不是一个好主意,因为它可能会导致一些奇怪的结果(None == None => true)。

您可以像这样使用flatMap而不是获取accountId的值

primaryIds = data.map(cd =>
        cd.flatMap{
           case Data(maybePrimaryId, Some(accountId)) if currentAccount.accountId.contains(accountId) => maybePrimaryId
          case _ => None
        }