我有一个case类A序列(id: UUID,profile: String,data: JsValue)
我想通过更新的从JsValue数据字段中对序列进行排序。
数据字段如下所示
{
"doors":2,
"color":"Black",
"updated":"2019-09-24T15:59:21+0200",
"username":"John",
"year":2016
}我尝试过sequenceOfA.sortWith(_.data \ "updated" < _.data \ "updated"),但这不起作用,因为<不是play's JsLookupResult的成员
将其转换为String也不起作用
sequenceOfA.sortWith((_.data \ "updated").as[String] < (_.data \ "updated").as[String])在Scala中,最惯用的方法是什么?
发布于 2020-03-02 21:15:19
您需要的是处理缺席字段。这可以通过更安全的方法通过显式处理来完成:
sequenceOfA.sortWith { case (left, right) =>
val leftUpdate = (left.data \ "update").validate[String].asOpt
val rightUpdate = (right.data \ "update").validate[String].asOpt
leftUpdate -> rightUpdate match {
case (Some(left), Some(right)) => left < right
case (None, Some(_)) => true // objects with `update` absent field goes first
case (Some(_), None) => false // objects with `update` present field goes after absent field
}
}或者只调用get方法,该方法可能引发异常--这是非常不推荐的:
sequenceOfA.sortWith((m \ "updated").as[String].get < (_.data \ "updated").as[String].get)希望这能有所帮助!
发布于 2020-03-02 21:16:40
一个潜在的解决办法可以是:
// Input is Seq[A] i.e val input: Seq[A]
// ConvertToTimestamp is a method which takes time as string and returns timestamp.
//This is required since time is in string and also timezones are involved.
//So this method will convert time string to UTC time(in epochs)
// def convertToTimeStamp(time: String): Long
val updated: Seq[Long] = A.map(value => (value.data \ "updated").as[String]).map(x => convertToTimestamp(x)) // fetch value
val pairs = input zip updated // List of ordered tuple
val sortedInput = pairs.sort(sortBy(pair => pair._2)).map(_._1).toSeq // sort using timestamp上面的解决方案假设updated字段不是空的。如果某些输入为空,则将解析该字段的函数更改为(在计算updated值时,如上面所示,要根据需求拥有一个默认值(如果您希望这些记录放在第一位,则为0;如果希望这些记录最后出现,则为Duration.Inf )。
如果有帮助请告诉我!!
https://stackoverflow.com/questions/60496121
复制相似问题