mutable.Map गहरा मर्ज

Dec 01 2020

क्या स्काला में दो परस्पर मानचित्रों को गहराई से मिलाने का एक संक्षिप्त तरीका है?

case class K1(i: Int)
case class K2(i: Int)

def deepMerge(map: mutable.Map[K1, Map[K2, List[Int]]],
              mergee: mutable.Map[K1, Map[K2, List[Int]]]
): Unit = ???

उदाहरण:

मैं।

val map = mutable.Map(K1(1) -> Map(K2(1) -> List(1)))
val mergee = mutable.Map(K1(1) -> Map(K2(1) -> List(2)))

deepMerge(map, mergee)
map = mutable.Map(K1(1) -> Map(K2(1) -> List(1, 2)))

II।

val map = mutable.Map(K1(1) -> Map(K2(1) -> List(1)))
val mergee = mutable.Map(K1(1) -> Map(K2(2) -> List(1)))

deepMerge(map, mergee)
map = mutable.Map(K1(1) -> Map(K2(1) -> List(1), K2(2) -> List(1)))

III।

val map = mutable.Map(K1(1) -> Map(K2(1) -> List(1)))
val mergee = mutable.Map(K1(2) -> Map(K2(2) -> List(1)))

deepMerge(map, mergee)
map = mutable.Map(K1(1) -> Map(K2(1) -> List(1)), K1(2) -> Map(K2(2) -> List(1)))

Ie यदि दोनों मानचित्रों में समान कुंजी प्रस्तुत की जाती है, तो जिन कुंजियों के अनुरूप ( List[Int]) विलय होता है।

क्या कोई तरीका है जिसे विशेष रूप से कुंजी प्रस्तुत करने या किसी अन्य मानचित्र में नहीं है, इसे बहुत सारी जाँच से बचने के लिए सहमति से लागू किया जा सकता है? स्केल या बिल्लियों की तरह एफपी लिबास का उपयोग करना भी ठीक है।

जवाब

3 KrzysztofAtłasik Dec 01 2020 at 15:40

मैं बिल्लियों का उपयोग करके एक और उत्तर जोड़ रहा हूं।

आप जो वर्णन कर रहे हैं, वह वास्तव में बिल्लियों का व्यवहार है । तो आप केवल संयोजन ( |+|) ऑपरेटर को गहरे मर्ज के नक्शे का उपयोग कर सकते हैं :

import cats.implicits._
import cats._

case class K1(i: Int)
case class K2(i: Int)

val map = Map(K1(1) -> Map(K2(1) -> List(1)))
val mergee = Map(K1(1) -> Map(K2(1) -> List(2)))

val deepMerged = map |+| mergee

println(deepMerged) // HashMap(K1(1) -> HashMap(K2(1) -> List(1, 2)))

समस्या यह है कि बिल्लियों के लिए परिचर्चा सेमेरीग्रुप का उदाहरण प्रदान नहीं करता है mutable.Map, लेकिन आप इसे अपरिवर्तनीय के लिए एक से प्राप्त कर सकते हैं:

import cats.implicits._
import scala.collection.immutable
import scala.collection.mutable
import cats._

//here I derivive Semigroup instance for mutable.Map from instance for immutable.Map
implicit def mutableMapSemigroup[K, V: Semigroup]: Semigroup[mutable.Map[K, V]] = Semigroup[immutable.Map[K, V]].imap(c => mutable.Map.from(c))(c => immutable.Map.from(c))

case class K1(i: Int)
case class K2(i: Int)

val map = mutable.Map(K1(1) -> mutable.Map(K2(1) -> List(1)))
val mergee = mutable.Map(K1(1) -> mutable.Map(K2(1) -> List(2)))

println(map |+| mergee)

लेकिन ध्यान रखें, यह वास्तव में उत्परिवर्तित मानचित्र को अपरिवर्तनीय में परिवर्तित करता है और फिर विलय में परिवर्तित करता है और फिर वापस परिवर्तनशील मानचित्र में परिवर्तित करता है, इसलिए यह संभवतः बहुत कुशल नहीं है।

1 jwvh Dec 01 2020 at 14:29

यह यह कर सकता है।

def deepMerge(mergeA: Map[K1, Map[K2, List[Int]]],
              mergeB: Map[K1, Map[K2, List[Int]]]
             ): Map[K1,Map[K2,List[Int]]] =
  (mergeA.toList ++ mergeB.toList).groupMap(_._1)(_._2).map{
    case (k1,ms) =>
      k1 -> ms.flatMap(_.toList).groupMap(_._1)(_._2).map{
        case (k2,ls) => k2 -> ls.flatten
      }
    }

मैंने इसे mutableमैप्स के साथ परीक्षण नहीं किया है, लेकिन इसे कमोबेश उसी तरह काम करना चाहिए।