我有一个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将引发异常。 有没有更好的方法来解决这个问题。请让我知道
答案 0 :(得分:1)
类似的事情应该起作用:
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
表示缺失值。这个小的更改将带来很大的不同,因为它简化了您处理数据的能力。
答案 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
}