Reputation: 3246
I have this two Map[String, String]
and I need to create new map with updated value. Update is done if second Map have new key or non-null value or value greater than of first Map.
For example:
Updating Scenario
FirstMap("key1" -> "123")
and SecondMap("key1" -> "456")
then ResultMap("key1" -> "456")
FirstMap("key1" -> null)
and SecondMap("key1" -> "value1")
then ResultMap("key1" -> "value1")
FirstMap()
and SecondMap("key1" -> "value1")
then ResultMap("key1" -> "value1")
Non-Updating Scenario
if FirstMap("key1" -> "value1")
and SecondMap()
then
ResultMap("key1" -> "value1")
if FirstMap("key1" -> "value1")
and SecondMap("key1" -> null)
then ResultMap("key1" -> "value1")
if FirstMap("key1" -> "789")
and SecondMap("key1" -> "456")
then ResultMap("key1" -> "789")
So far I have code below:
val currentFieldValue = currentDetail.get(field).get
val newFieldValue = newDetail.get(field).get
currentFieldValue match {
case null if newFieldValue != null => currentDetail ++ Map(s"$field" -> s"$newFieldValue")
case _ if newFieldValue != null && newFieldValue.toInt > currentFieldValue.toInt => currentDetail ++ Map(s"$field" -> s"$newFieldValue")
case _ => currentDetail
}
Any suggestion on how to accommodate None
state i.e. when key itself itsn't there?
Upvotes: 1
Views: 215
Reputation: 51271
def combine(m1: Map[String,String], m2: Map[String,String]): Map[String,String] =
(m1.keys ++ m2.keys).toSet.map{ k: String =>
k -> Seq(Option(m1.getOrElse(k,"")), Option(m2.getOrElse(k,"")), Some(""))
.flatten.sorted.reverse.head
}.toMap
"456" > "123"
is true for both String
and Int
. What if you have two strings "99"
and "101"
? If you need number comparisons then that's going to require lots more code to transit between String
->Int
->String
.
Upvotes: 1
Reputation: 434
just as alternative here is complete compare function (with debug msgs):
def compare(currentDetail: Map[String, String], newDetail: Map[String, String]): Map[String, String] = {
var resMap = Map[String, String]()
currentDetail.keys.foreach { field =>
val currentField = currentDetail.get(field)
val newField = newDetail.get(field)
resMap = resMap + {
(currentField, newField) match {
case (Some(null), Some(newFieldValue: String)) =>
println("null and not null")
(s"${field}" -> newFieldValue)
case (Some(currentFieldValue), Some(null)) =>
println("not null and null")
(s"${field}" -> currentFieldValue)
case (None, Some(newFieldValue)) =>
println("none and not null")
(s"${field}" -> newFieldValue)
case (Some(currentFieldValue), None) =>
println("not null and none")
(s"${field}" -> currentFieldValue)
case (Some(currentFieldValue), Some(newFieldValue)) if newFieldValue.toInt > currentFieldValue.toInt =>
println("not null not null if new bigger then current")
(s"${field}" -> newFieldValue)
case (Some(currentFieldValue), Some(newFieldValue)) if newFieldValue.toInt <= currentFieldValue.toInt =>
println("not null not null if new less or equal to current")
(s"${field}" -> currentFieldValue)
}
}
}
resMap
}
Upvotes: 1
Reputation: 14825
map.get(key)
returns Option
pattern match on the option and create as many relevant cases as you want
(currentDetail.get(field), newDetail.get(field)) match {
case (Some(null), Some(null)) =>
case (Some(null), Some(value)) =>
case (Some(value), Some(null)) =>
case (Some(value), None) =>
case (None, Some(value)) =>
case (None, None) =>
case (_, _) =>
}
Upvotes: 1