我试图从第三方JSON消息中提取(时间戳,值)元组:
{
"data": {
"1496845320000": [
0.14
],
"1496845380000": [
0.14
],
"1496845560000": [
0.14
],
"1497013740000": [
"undef"
],
"1497013800000": [
"undef"
],
"1497013860000": [
"undef"
]
},
"status": "ok"
}
这就是我提取JSON实体的方式:
val batchReadings = http.singleRequest(httpRequest) map {
case HttpResponse(StatusCodes.OK, headers, entity, _) =>
entity.dataBytes.runFold(ByteString(""))(_ ++ _).foreach { body =>
JSON.parseFull(body.utf8String) match {
case Some(e: Map[String, Any]) =>
e.get("status") match {
case Some("ok") => println("ok!")
e.get("data") match {
case Some(f: Map[String, List[Any]]) =>
println("entered second case")
new EfergyReadingsData(f.toList).getReadings
}
case _ => log.info("EfergyReaderWorkerActor: Received unknown message\n" + body.utf8String)
}
}
}
case HttpResponse(code, _, entity, _) =>
//entity.toStrict(100, materializer) N.B. Not having this, will freeze after 4 calls!
s"Response code: $code"
case unknown =>
s"unknown response: $unknown"
}
这是EfergyReadingsData类:
class EfergyReadingsData(readings: List[(String, List[Any])]) {
def getReadings: List[(Long, Double)] = {
println(readings)
// List((1123, 34.4))
val filteredReadings = readings filter {
f =>
f._2 match {
case t:List[Any] =>
t.head match {
case Double => true
case _ => false
}
}
}
val theRead = filteredReadings map {
p => (p._1.toLong, p._2.head)
}
println(theRead)
List((1123, 34.4))
}
}
正如您所看到的那样,我没有返回我在getReadings
中应该使用的元组列表,我只是创建了一个要返回的列表,以便我可以测试代码。
除了无法过滤列表以仅删除undef
条目(filteredReadings
为空)之外,这种方法的第一个明显问题是我对类型的模式匹配在List和Map中,因此得到一个关于那些未被检查的警告,因为它们被擦除消除了。
虽然为简单起见没有在上面表示,但我试图通过使用列表的案例类来缓解这个问题:
sealed abstract class AnyReading {
val value: List[Any]
}
case class SuccessfulReading(override val value: List[Double]) extends AnyReading
case class FailedReading(override val value: List[String]) extends AnyReading
因此,总结一下,最好的方法是什么?我还考虑创建几个案例类来表示JSON结构,并尝试反序列化JSON消息,然后过滤以删除undef
值,最终得到我想要的元组列表。
提前感谢您的帮助。