scala - 从Option [String]中提取值的scala方式是什么?
问题描述
我正在尝试从 Option[String] 中提取辅助和 event_type 提取这些值的最佳 scala 方法是什么,如果没有,则将 null 作为输出。
val payload = Some({"event":"testApi",
"data":[{"aid":"test","pr":"{\"id\":\"813da0e5-d9aa-4275-b9d4-5e84362b73bb\",\"event_type\":\"promo app loaded\",\"label\":\"beach apartheid\",\"total\":1,\"timestamp\":1617891494152}}]",
"tv":"js-2.17.3"
})
如果我有这个如何提取其他然后如果其他。
解决方案
这取决于您之后将如何处理此有效负载。Option
是一个monad,所有标准操作,如.map
, flatMap
, .foreach
,.filter
等都.collect
适用于它。我真的建议您阅读scala monads以更好地处理它。
简而言之,你应该构建你的代码,这样你就不需要做任何事情option.get
来访问实际值,几乎从不做option.isEmpty
(或者option.nonEmpty
,如果曾经做的话,也很少做.getOrElse
(例如val unwrappedJson = payload.getOrElse('{}')
)。
在大多数情况下,我也会避免模式匹配,尽管该书在另一个答案中提到了这一点。它可能是“最常见的”,但在大多数情况下不是“最好的”(虽然,这开始进入“个人品味”领域,模式匹配在技术上没有任何问题,只是它不是“单子的” ",因此在视觉上更难阅读和解析)。
您可以做的一些事情的例子:
def parsePayload(maybePayload: Option[String]): Option[Payload] =
maybePayload.map(json.readValue[Payload])
...
def getLabels(maybePayload: Option[String]): Seq[String] = maybePayload
.map(json.readValue[Payload])
.toSeq
.flatMap(_.data)
.map(_.pr.label)
...
def uniqueIds(maybePayload: Option[String]): Seq[String] = maybePayload
.map(json.readValue[Payload])
.toSeq
.flatMap(_.data)
.map(_.pr.id)
.distinct
...
def maybeData(maybePayload: Option[String]): Seq[Data] =
parsePayload(maybePayload)
.fold(Seq.empty[Data])(_.data)
...
def byId(maybePayload: Option[String]): Map[String, Seq[Data]] = maybePayload
.map(json.readValue[Payload])
.toSeq
.flatMap(_.data)
.groupBy(_.pr.id)
.map { case(id, datas) => datas }
def forId(maybePayload: Option[String], id: String): Seq[Data] = maybePayload
.map(json.readValue[Payload])
.toSeq
.flatMap(_.data.filter(_.pr.id == id))
...
def forId2(maybePayload: Option[String], id: String): Seq[Data] =
byId(maybePayload).getOrElse(id)
...
def maxTotal(maybePayload: Option[String]): Option((String, Int)) =
parsePayload(maybePayload)
.collect { case Payload(_, data, _) if data.nonEmpty => data.maxBy(_.pr.total) }
.map { case data => data.pr.id -> data.pr.total }
...
def printPayload(maybePayload: Option[String]): Unit =
maybePayload.foreach(println)
等等。
推荐阅读
- c# - C# 和 C++ 库(FILE * 类型)
- python - 如何对熊猫中的多个新列进行相同的计算?
- android - 无法从 xml 文件访问 androidx.navigation.fragment.NavHostFragment
- javascript - 使用 react-navigation 重新加载或重新渲染活动
- java - Kotlin:在 sample.jar 中没有主要清单属性
- opencv - 使用 ffmpeg 将 opencv 流式传输到 youtube
- linux - Apache 将 HTTPS 重定向到 HTTP
- python - 如何将 matplotlib 中的图形写入 excel 文件
- javascript - 以特定方式导入JS
- python - 如何在 Python 中动态修改系列输入或变量?