2014-05-09 5 views
5

क्लोजर में डिफ फ़ंक्शन नक्शे पर लागू किया जा सकता है, जो स्कैला में ऐसा प्रतीत नहीं होता है, क्या किसी को स्कैला में कुछ पता है जो क्लोजर डिफ फ़ंक्शन को लागू होने पर प्राप्त करने के लिए और अधिक सुलभ बना देगा नक्शे के लिए?क्या स्कैला, या लाइब्रेरी में क्लोजर के डिफ के बराबर नक्शे पर लागू होने के समान मौजूद है?

यहां क्लोजर diff फ़ंक्शन संदर्भ के लिए समझाया गया है।

http://clojuredocs.org/clojure_core/clojure.data/diff

उत्तर

2

जैसा कि अन्य ने कहा है कि ऐसा कुछ नहीं है, लेकिन आप इसे किसी भी तरह से बना सकते हैं। यहां मेरा प्रयास है जो मैप क्लास के साथी के रूप में जोड़ा जाता है। यह क्लोजर diff उदाहरण के रूप में एक ही परिणाम पैदा करता है।

object MapsDemo extends App{ 
    implicit class MapCompanionOps[A,B](val a: Map[A,B]) extends AnyVal { 
    def diff(b: Map[A,B]): (Map[A,B],Map[A,B],Map[A,B]) = { 
      (a.filter(p => !b.exists(_ == p)), //things-only-in-a 
      b.filter(p => !a.exists(_ == p)), //things-only-in-b 
      a.flatMap(p => b.find(_ == p))) //things-in-both 
     } 
    } 

    val uno = Map("same" ->"same","different" -> "one") 
    val dos = Map("same" ->"same","different" -> "two","onlyhere"->"whatever") 
    println(uno diff dos) //(Map(different -> one),Map(different -> two, onlyhere -> whatever),Map(same -> same)) 
    println(Map("a"->1).diff(Map("a"->1,"b"->2))) //(Map(),Map(b -> 2),Map(a -> 1)) 
} 
1

आप पहली सूची नक्शे परिवर्तित करके कि प्राप्त कर सकते हैं। उदाहरण के लिए:

scala> val a = Map(1->2, 2-> 3).toList 
scala> val b = Map(1->2, 3-> 4).toList 
scala> val closureDiff = List(a.diff(b), b.diff(a), a.intersect(b)) 
closureDiff: List[List[(Int, Int)]] = List(List((2,3)), List((3,4)), List((1,2))) 
+1

यह वह जगह है सबसे अच्छा। आप सूचियों को वापस मैप के साथ मानचित्र पर बदल सकते हैं i.e. 'a.diff (b) .toMap' – Gangstead

+0

इसका उपयोग कर सकते हैं, हालांकि सूची में कनवर्ट करने के लिए मुझे उम्मीद से थोड़ा कम इष्टतम था। – RatavaWen

0

मानक लाइब्रेरी में कोई फ़ंक्शन नहीं है जो आपको वही करता है जो आपको चाहिए। हालांकि, इस तरह से एक अन-अनुकूलित संस्करण आसानी से कार्यान्वित किया जा सकता है (पहली कोशिश में "अवधि" गलती के लिए खेद है)।

डीईएफ़ diffffK, वी: (मानचित्र [कश्मीर, V], मानचित्र [कश्मीर, V], मानचित्र [कश्मीर, V]) = {

val (both,left) = m1.partition({case (k,v) => m2.get(k) == Some(v) }) 
val right = m2.filter({case (k,v) => both.get(k) != Some(v) }) 
(both,left,right) 

}

भी, एक नक्शा कर सकते हैं एक ऑपरेटर (टूसेट) के साथ एक सेट में परिवर्तित किया जाना चाहिए और फिर आप सेट के अवरोध, संघ और diff ऑपरेटरों का उपयोग कर सकते हैं।

+0

अवधि काम नहीं कर रही है क्योंकि यह केवल एक बिंदु पर काम करती है, इसलिए एक बार जब यह एक अलग मूल्य केवी जोड़े को हिट करता है तो यह अलग-अलग केवी जोड़े के रूप में निम्नलिखित सभी को लुप्त करता है, भले ही वे नहीं हैं। मैंने आंशिक के साथ चारों ओर घूमने की कोशिश की और यह उपयोगी हो सकता है (यह अलग-अलग केवी जोड़े को बाकी से अलग कर रहा है), लेकिन मुझे अभी तक पता नहीं चला है कि क्लोजर फ़ंक्शन से मेल खाने के लिए इसे कैसे प्राप्त किया जाए। लेकिन यह मुझे उस दिशा में प्रगति करने में मदद कर रहा है। – RatavaWen

4

यह Clojure के diff के बराबर है:

import collection.generic.CanBuildFrom 

def diff[T, Col](x: Col with TraversableOnce[T], y: Col with TraversableOnce[T]) 
     (implicit cbf: CanBuildFrom[Col, T, Col]): (Col, Col, Col) = { 
    val xs = x.toSet 
    val ys = y.toSet 
    def convert(s: Set[T]) = (cbf(x) ++= s).result 
    (convert(xs diff ys), convert(ys diff xs), convert(xs intersect ys)) 
} 

यह TraversableOnce के किसी भी प्रकार पर काम कर सकते हैं और उसके मानदंड के रूप में एक ही प्रकार के साथ परिणाम देंगी:

scala> diff(Map(1 -> 2), Map(1 -> 2)) 
res35: (scala.collection.immutable.Map[Int,Int], scala.collection.immutable.Map[Int,Int], scala.collection.immutable.Map[Int,Int]) = (Map(),Map(),Map(1 -> 2)) 
संबंधित मुद्दे