Reputation: 1010
The context is comparing two Map's keys and values in Scala, but I'm not sure I even know how to ask this properly. Let's say I have two case classes
case class WhiteList(attributes: Option[Map[String, Set[String]]])
and
case class Query(attributes: Option[Map[String, Set[String]]])
I want to compare the values of attributes between this two classes if the key in the attributes map is the same and otherwise return false
.
So, if I had
val wl = WhiteList(attributes = Some(Map("patterns" -> Set("plaid"),
"colors" -> Set("blue", "orange")))
and
val q = Query(attributes = Some(Map("patterns" -> Set("plaid"),
"colors" -> Set("orange")))
If I compared these two, I want to return true
because:
1) they have same Map keys and
2) the values of the corresponding keys intersect
If I had
val q2 = Query(attributes = Some(Map("patterns" -> Set("stripes"),
"colors" -> Set("orange", "red", "blue")))
and compared values of corresponding keys to wl, I want false
because "patterns" value doesn't intersect.
If I had
val q3 = Query(attributes = Some(Map("starwars" -> Set("a new hope", "empire strikes back"),
"patterns" -> Set("stripes"),
"colors" -> Set("orange", "red", "blue")))
and compared q3 to wl, I'd expect false
, because attribute's keys are not one-to-one.
I'm thinking there has to be a functional way to do this.
Upvotes: 1
Views: 5781
Reputation: 8663
Maybe like this?
def areEqual(wl: WhiteList, q: Query) = (wl, q) match {
case (WhiteList(Some(map1)), Query(Some(map2))) =>
map1.keySet == map2.keySet &&
map1.keySet.forall(key => (map1(key) intersect map2(key)).nonEmpty)
case _ => false
}
Test in repl:
val wl = WhiteList(attributes = Some(Map("patterns" -> Set("plaid"),
"colors" -> Set("blue", "orange"))))
val q = Query(attributes = Some(Map("patterns" -> Set("plaid"),
"colors" -> Set("orange"))))
val q2 = Query(attributes = Some(Map("patterns" -> Set("stripes"),
"colors" -> Set("orange", "red", "blue"))))
val q3 = Query(attributes = Some(Map("starwars" -> Set("a new hope", "empire strikes back"),
"patterns" -> Set("stripes"),
"colors" -> Set("orange", "red", "blue"))))
scala> areEqual(wl, q)
res4: Boolean = true
scala> areEqual(wl, q2)
res5: Boolean = false
scala> areEqual(wl, q3)
res6: Boolean = false
Upvotes: 3