Merge maps by key

前端 未结 8 2102
不思量自难忘°
不思量自难忘° 2020-12-01 05:14

Say I have two maps:

val a = Map(1 -> \"one\", 2 -> \"two\", 3 -> \"three\")
val b = Map(1 -> \"un\", 2 -> \"deux\", 3 -> \"trois\")


        
相关标签:
8条回答
  • 2020-12-01 06:15
    val fr = Map(1 -> "one", 2 -> "two", 3 -> "three")
    val en = Map(1 -> "un", 2 -> "deux", 3 -> "trois")
    
    def innerJoin[K, A, B](m1: Map[K, A], m2: Map[K, B]): Map[K, (A, B)] = {
      m1.flatMap{ case (k, a) => 
        m2.get(k).map(b => Map((k, (a, b)))).getOrElse(Map.empty[K, (A, B)])
      }
    }
    
    innerJoin(fr, en) // Map(1 -> ("one", "un"), 2 -> ("two", "deux"), 3 -> ("three", "trois")): Map[Int, (String, String)]
    
    0 讨论(0)
  • 2020-12-01 06:16

    So I wasn't quite happy with either solution (I want to build a new type, so semigroup doesn't really feel appropriate, and Infinity's solution seemed quite complex), so I've gone with this for the moment. I'd be happy to see it improved:

    def merge[A,B,C](a : Map[A,B], b : Map[A,B])(c : (B,B) => C) = {
      for (
        key <- (a.keySet ++ b.keySet);
        aval <- a.get(key); bval <- b.get(key)
      ) yield c(aval, bval)
    }
    merge(a,b){Seq(_,_)}
    

    I wanted the behaviour of returning nothing when a key wasn't present in either map (which differs from other solutions), but a way of specifying this would be nice.

    0 讨论(0)
提交回复
热议问题