Todd M
Todd M

Reputation: 1010

Scala comparing two Map's keys and values

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

Answers (1)

Łukasz
Łukasz

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

Related Questions