2017-12-05 4 views
1

diesem Code MitZusammenführen von zwei LinkedHashMap in Scala

def mergeWith[K, X, Y, Z](xs: mutable.LinkedHashMap[K, X], ys: mutable.LinkedHashMap[K, Y])(f: (X, Y) => Z): mutable.LinkedHashMap[K, Z] = 
    xs.flatMap { 
    case (k, x) => ys.get(k).map(k -> f(x, _)) 
    } 

es gibt mir dies:

val map1 = LinkedHashMap(4 -> (4), 7 -> (4,7)) 
val map2 = LinkedHashMap(3 -> (3), 6 -> (3,6), 7 -> (3,7)) 

val merged = mergeWith(map1,map2){ (x, y) => (x, y) } 
merged: scala.collection.mutable.LinkedHashMap[Int,(Any, Any)] = Map(7 -> ((4,7),(3,7))) 

Aber was ich will, ist dies:

merged: scala.collection.mutable.LinkedHashMap[Int,(Any, Any)] = Map(3 -> (3), 4 -> (4), 6 -> (3,6), 7 -> ((4,7),(3,7))) 

Wie kann ich meinen Code ändern, um ihn zu erhalten?

Antwort

1

Es kann nicht mit der aktuellen Signatur mergeWith() durchgeführt werden. Insbesondere versuchen Sie, einen LinkedHashMap[K,Z] zu erstellen, aber es gibt keinen Z Eingang. Die einzige Möglichkeit, eine Z zu erhalten, besteht darin, f() aufzurufen, die sowohl X als auch Y als übergebene Parameter erfordert.

Also, wenn xs ist LinkedHashMap[Int,Char] Typ und hat Element (2 -> 'w') und ys ist LinkedHashMap[Int,Long] Typ und hat Element (8 -> 4L), wie wollen Sie f(c:Char, l:Long) so aufrufen, dass Sie einen [K,Z] Eintrag für beide Tasten 2 und 8? Nicht möglich.

Wenn die mergeWith() Signatur vereinfacht werden kann, könnten Sie etwas ähnliches tun.

def mergeWith[K,V](xs: collection.mutable.LinkedHashMap[K, V] 
        ,ys: collection.mutable.LinkedHashMap[K, V] 
       )(f: (V, V) => V): collection.mutable.LinkedHashMap[K,V] = { 
    val ns = collection.mutable.LinkedHashMap[K,V]() 
    (xs.keySet ++ ys.keySet).foreach{ k => 
    if (!xs.isDefinedAt(k)) ns.update(k, ys(k)) 
    else if (!ys.isDefinedAt(k)) ns.update(k, xs(k)) 
    else ns.update(k, f(xs(k), ys(k))) 
    } 
    ns 
} 

Dies erzeugt das gewünschte Ergebnis für das Beispiel, das Sie gegeben haben, aber es hat eine Reihe von unerwünschten Eigenschaften hat, nicht zuletzt von denen die veränderbaren Datenstrukturen sind.

Übrigens gibt es keine Tuple1 so (4) ist das gleiche wie 4. Und wann immer Sie den Typ Any sehen, ist es ein gutes Zeichen, dass Ihr Design neu überdacht werden muss.

Verwandte Themen