在Scala中,如何从一组地图中获取最大日期,其中地图中的一个键是“日期”?

时间:2013-08-23 18:18:32

标签: arrays scala scala-collections

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

有更好的方法吗?我担心我需要假设像将值转换为Date进行比较,但这就是Map中的内容,而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的方式。

3 个答案:

答案 0 :(得分:1)

这个小小的衬垫有效,但如果任何地图中没有日期,它会抛出异常:

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))

答案 1 :(得分:0)

omap.maxBy{ _("date").asInstanceOf[Date] }

答案 2 :(得分: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
    }
  }
})

将所有无日历地图随机播放到最后。