java - Scala HashMap from an Array -
i have scala array of 2-tuples this:
(("a", "2015-11-01"), ("b", "2016-11-11"), ("a", "2017-11-01"), ("b", "2013-11-11"))
i want create map key maps latest date. so, in example above, result should be:
map ("a" -> "2017-11-01", "b" -> "2016-11-11")
i know how iteratively - scala-way (functional-way) this?
first groupby key , pick latest date.
arr .groupby(_._1) .map { case (k, v) => k -> v.maxby(_._2)._2 }
use mapvalues
make shorter
arr.groupby(_._1).mapvalues(_.maxby(_._2)._2)
as date (string) formatted max date latest date. need not convert date time in millis decide max date.
scala repl
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 finish) arr .groupby(_._1) .map { case (k, v) => k -> v.maxby(_._2)._2 } // exiting paste mode, interpreting. res0: scala.collection.immutable.map[string,string] = map(a -> 2017-11-01, b -> 2016-11-11)
date conversion not needed if wish convert go ahead.
date conversion:
//ensure correct date format given method if not throw match error @ 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(); }
solution:
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 repl
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)
Comments
Post a Comment