1

我有一组地图和地图,我想在地图数组中找到最大日期,我想我正在沿着非 scala 路径前进,因为我不确定如何连接这个问题的各个部分一起。

有没有更好的方法来做到这一点?我担心我需要假设诸如将值转换为 Date 进行比较之类的事情,但这就是 Map 中的内容,并且地图还包括其他数据类型(所以 Map[String, Object] 是我所拥有的)

val df = new SimpleDateFormat("yyyy-MM-dd")     
def omap = List(Map("date" -> df.parse("2013-08-01")), Map("date" -> df.parse("2013-02-01"), "otherkey" -> "nothing special"), Map("date" -> df.parse("2013-01-01")))
omap.max(new Ordering[Map[String, Object]] {
  def compare(x: Map[String, Object], y: Map[String, Object]) = x.get("date").get.asInstanceOf[Date] compareTo y.get("date").get.asInstanceOf[Date]
}) 

代码似乎有效,但我觉得我错过了一种更像 scala 的方式。

4

3 回答 3

2

这个小班轮可以工作,但如果任何地图中都没有日期,它会抛出异常:

omap.flatMap(map => map.get("date").collect({case d:Date => d})).max

这是一个更安全的版本,但您必须提供默认日期:

  val defaultDate = new Date()
  omap.map(map => map.get("date").collect({case d:Date => d}))
    .foldLeft(defaultDate)((default, od) => od.fold(default)( d => if (d.compareTo(default) > 0) d else default))
于 2013-08-23T19:10:27.400 回答
0
omap.maxBy{ _("date").asInstanceOf[Date] }
于 2013-08-23T18:26:39.283 回答
0

如果您有最少数量的类型,您可能应该使用类似Either. 但我会假设你有太多的。

然后,获取您的价值的更规范的方法是这样的(替换您的omap.max):

val defaultDate = df.parse("1970-01-01")

def dateFrom(m: Map[String, Object]) =
  m.get("date").collect{ case d: Date => d }.getOrElse(defaultDate)

omap.maxBy(dateFrom)

这可以通过将所有丢失的内容分组到最早的可能日期来保护您免受丢​​失条目的影响。

如果您没有任何合理的默认日期,那么

def dateFrom(m: Map[String, Object]) = m.get("date").collect{ case d: Date => d }
omap.max(new Ordering[Map[String, Object]] {
  def compare(x: Map[String, Object], y: Map[String, Object]) = {
    (dateFrom(x), dateFrom(y)) match {
      case (Some(a), Some(b)) => a compareTo b
      case (_, None) => -1
      case _         => 1
    }
  }
})

将所有无日期的地图洗牌到最后。

于 2013-08-23T19:00:51.027 回答