首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >来自数组的Scala HashMap

来自数组的Scala HashMap
EN

Stack Overflow用户
提问于 2016-11-06 04:35:54
回答 2查看 530关注 0票数 1

我有一个由2元组组成的Scala数组,如下所示:

代码语言:javascript
复制
(("A", "2015-11-01"), ("B", "2016-11-11"), ("A", "2017-11-01"), ("B", "2013-11-11"))

我想创建一个地图,其中的关键字映射到最新的日期。因此,在上面的示例中,结果应该是:

代码语言:javascript
复制
Map ("A" -> "2017-11-01", "B" -> "2016-11-11")

我知道如何迭代--但是什么是Scala方式(函数式方式)来做到这一点?

EN

回答 2

Stack Overflow用户

发布于 2016-11-06 04:47:02

首先选择groupBy密钥,然后选择最新日期。

代码语言:javascript
复制
arr
  .groupBy(_._1)
  .map { case (k, v) => k -> v.maxBy(_._2)._2 }

使用mapValues使其更短

代码语言:javascript
复制
arr.groupBy(_._1).mapValues(_.maxBy(_._2)._2)

由于日期(字符串)的格式正确,因此最大日期是最晚日期。您不需要将日期转换为时间来决定最大日期。

Scala

代码语言:javascript
复制
scala> val arr = Array(("A", "2015-11-01"), ("B", "2016-11-11"), ("A", "2017-11-01"), ("B", "2013-11-11"))
arr: Array[(String, String)] = Array((A,2015-11-01), (B,2016-11-11), (A,2017-11-01), (B,2013-11-11))

scala> :paste
// Entering paste mode (ctrl-D to finish)

arr
  .groupBy(_._1)
  .map { case (k, v) => k -> v.maxBy(_._2)._2 }


// Exiting paste mode, now interpreting.

res0: scala.collection.immutable.Map[String,String] = Map(A -> 2017-11-01, B -> 2016-11-11)

日期转换是不需要的,但如果你想转换它,那就继续吧。

日期转换:

代码语言:javascript
复制
//ensure correct date format is given to this method if not it will throw match error at runtime.
def convertStringDateToMillis(str: String): Long = {
 val regex = "(\\d{4})-(\\d{2})-(\\d{2})".r.unanchored
 val regex(year, month, day) = str
 val calendar = Calendar.getInstance()
 calendar.clear()
 calendar.set(Calendar.MONTH, month.toInt)
 calendar.set(Calendar.YEAR, year.toInt)
 calendar.set(Calendar.DAY_OF_MONTH, month.toInt)
 calendar.getTimeInMillis();
}

解决方案:

代码语言:javascript
复制
val arr = Array(("A", "2015-11-01"), ("B", "2016-11-11"), ("A", "2017-11-01"), ("B", "2013-11-11"))

arr.groupBy(_._1).map { case (k, v) => k -> v.maxBy(convertStringDateToMillis(_._2))._2 }

Scala

代码语言:javascript
复制
scala> def convertStringDateToMillis(str: String): Long = {
     |  val regex = "(\\d{4})-(\\d{2})-(\\d{2})".r.unanchored
     |  val regex(year, month, day) = str
     |  val calendar = Calendar.getInstance()
     |  calendar.clear()
     |  calendar.set(Calendar.MONTH, month.toInt)
     |  calendar.set(Calendar.YEAR, year.toInt)
     |  calendar.set(Calendar.DAY_OF_MONTH, month.toInt)
     |  calendar.getTimeInMillis();
     | }
convertStringDateToMillis: (str: String)Long

scala> val arr = Array(("A", "2015-11-01"), ("B", "2016-11-11"), ("A", "2017-11-01"), ("B", "2013-11-11"))
arr: Array[(String, String)] = Array((A,2015-11-01), (B,2016-11-11), (A,2017-11-01), (B,2013-11-11))


scala> arr.groupBy(_._1).map { case (k, v) => k -> v.maxBy(x => convertStringDateToMillis(x._2))._2 }
res3: scala.collection.immutable.Map[String,String] = Map(A -> 2017-11-01, B -> 2016-11-11)
票数 3
EN

Stack Overflow用户

发布于 2016-11-06 05:37:58

像这样的东西应该是有效的:

代码语言:javascript
复制
array
  .groupBy(_._1)
  .mapValues(_.map(_._2).max)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40442939

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档