2011-05-08 4 views
15

कहें कि मेरे पास एक चर x है, और मैं यह जांचना चाहता हूं कि यह किसी भी मान, बी, सी, डी, ई के किसी भी एक के बराबर है या नहीं (मेरा मतलब है == समानता, पहचान नहीं)।स्कैला में, एकाधिक मूल्यों के साथ एक मान की तुलना करने के लिए एक साफ और सरल तरीका है

एक SQL क्वेरी में इसी अवधारणा

WHERE x IN (a, b, c, d, e). 

साथ नियंत्रित किया जाता है वहाँ स्काला में कुछ बराबर है कि उस के रूप में के रूप में सीधा है है? मुझे पता है कि इसे एक जटिल अभिव्यक्ति के साथ एक पंक्ति में करना संभव है जैसे कि हैशसेट बनाना और सेट में अस्तित्व की जांच करना, लेकिन अगर यह उपलब्ध है तो मैं एक साधारण निर्माण का उपयोग करना पसंद करूंगा।

उत्तर

20

मैं पसंद करेंगे contains(a)exists(_ == a) से अधिक:

scala> List(3, 4, 5) contains 4 
res0: Boolean = true 

scala> List(3, 4, 5) contains 6 
res1: Boolean = false 

अद्यतन: containsSeqLike में परिभाषित किया गया है, इसलिए किसी भी क्रम के साथ ऊपर काम करता है।

अद्यतन 2: यहाँ SeqLike में contains की परिभाषा है:

def contains(elem: Any): Boolean = exists (_ == elem) 
+1

मुझे खेद है, मैंने आपको वोट दिया, क्योंकि मैंने सोचा था कि 'शामिल' पहचान के साथ काम करेगा, समानता के साथ नहीं। मैंने आपको वोट दिया और मेरे जवाब में एक लंबा सबूत लिखना शुरू कर दिया, लेकिन इसके बजाय मैंने खुद को गलत साबित कर दिया। माफ़ कीजिये। :) –

+0

@user और मैंने आपके उत्तर को वोट दिया क्योंकि जैसा कि आप मेरे दूसरे अपडेट में देख सकते हैं '(ए)' केवल मौजूद है (_ == ए) 'के लिए चीनी है, इसलिए हमारे उत्तर समकक्ष हैं। –

+0

यह सिर्फ चीनी हो सकता है, लेकिन मैं एक मीठा हूं, और चूंकि आपने अपना जवाब संपादित किया है, इसलिए मैं अपना मतदान सही कर सकता हूं। (स्कैला जावा के लिए सिंटैक्टिक चीनी है, जो असेंबलर के लिए सिंटेक्टिक चीनी है ...)। –

5

मौजूद है:

List (3, 4, 5).exists (_ == 4) 
// res20: Boolean = true 

खोजें और फिल्टर करीब आ:

List (3, 4, 5).find (_ == 4) 
// res16: Option[Int] = Some(4) 
List (3, 4, 5).filter (_ == 4) 
// res17: List[Int] = List(4) 

मेरा पहला जवाब था, अन्य उत्तर के रूप में, शामिल उपयोग करने के लिए:

List (3, 4, 5).contains (4) 

लेकिन फिर मैंने सोचा , यह केवल कक्षाओं के लिए बॉक्सिंग मानों के लिए काम करेगा, कक्षाओं के लिए नहीं, जो पहचान और समानता को अलग करता है। यह साबित करने के लिए, मैं एक छोटे से वर्ग है, जो साबित कर दिया मुझे गलत लिखा है: :)

class Ue (val i: Int) { 
    override def equals (other: Any) = other match { 
    case o: Ue => i == o.i 
    case _ => false } 
} 

val a = new Ue (4) 
// a: Ue = [email protected] 
val b = new Ue (4) 
// b: Ue = [email protected] (no identity) 
a == b 
// res110: Boolean = true (surprise?) 
a.equals (b) 
// res112: Boolean = true (expected) 
a.eq (b) 
// res113: Boolean = false (expected) 
List (a).contains (b)  
// res119: Boolean = true (surprise) 
List (a).exists (_ == b) 
// res120: Boolean = true (expected) 
List (a).exists (_ .eq (b)) 
// res121: Boolean = false (expected) 

मैं देख रहा हूँ, मैं का उपयोग करने के बराबर है/eq/अधिक बार ==, मेरे मस्तिष्क में भेद पाने के लिए।

List (3, 4, 5).contains (4) 

आईएमओ उत्तर है जो सबसे आसान है।

23

आप इस प्रकार एक in ऑपरेटर को लागू कर सकते हैं:

scala> implicit def anyWithIn[A](a: A) = new { 
    | def in(as: A*) = as.exists(_ == a) 
    | } 
anyWithIn: [A](a: A)java.lang.Object{def in(as: A*): Boolean} 

scala> 5 in (3, 4, 9, 11) 
res0: Boolean = false 

scala> 5 in (3, 4, 9, 11, 5) 
res1: Boolean = true 
+2

यह बहुत खूबसूरत है। मेरे सभी प्रोजेक्ट्स में समाप्त होने वाले मानक एक्सटेंशन के अपने सेट में सही हो जाता है, और तर्कसंगत रूप से मानक लाइब्रेरी समावेशन –

+1

योग्यता देता है * यह * अन्य * तरीके से इसे कैसे करें: यानी एक 'ए => बूलियन' लिख सकते हैं '5 ∈: सेट (1, 2, 3, 4, 5)' –

+1

साफ! इसे स्कैला के अगले संस्करण में बनाया जाना चाहिए। लेकिन जैसा कि है, इसके लिए इसे हर जगह निहित रूपांतरण को स्पष्ट रूप से आयात या विरासत की आवश्यकता होगी, इसलिए अब मैं सूची/तकनीक के साथ जा रहा हूं। – Gigatron

12

यह देखते हुए कि एक Set[A] भी एक A => Boolean है, तो आप सिर्फ कह सकते हैं:

Set(a, b, c, d, e) apply x 

यह वास्तव में परिभाषित करने के लिए काफी अच्छा है इसके लिए कुछ पिंपिन 'चीनी:

class PredicateW[A](self : A => Boolean) { 
    def ∈:(a : A) = self apply a 
} 
implicit def pred2wrapper[A](p : A => Boolean) = new PredicateW(p) 

तो फिर तुम कोड इसलिए की तरह लिख सकते हैं:

x ∈: Set(a, b, c, d, e) 
+2

एक और साफ समाधान, धन्यवाद। लेकिन मेरे पास मेरे यूएस कीबोर्ड पर '∈' प्रतीक नहीं है! बोल्डिंग के लिए – Gigatron

8

सभी अन्य उत्तर synthesizing, मैं सही जवाब के साथ आए हैं:

implicit def anyWithIn[A](a: A) = new { 
    def ∈(as: A*) = as.contains(a) 
} 
anyWithIn: [A](a: A)java.lang.Object{def ?(as: A*): Boolean} 

5 ∈ (1,3,5) 
res1: Boolean = true 

टा-दा।

+1

+1। – Landei

+0

अरे, मैं इसे अब तक दिए गए किसी भी अन्य उत्तर से अधिक बेहतर प्रदर्शन के रूप में रक्षा करूंगा (लापता होने वाले समाधान की तुलना में अधिक सुगम, ऑक्सबो_लेक्स की तुलना में अधिक अनुकरणीय, अधिक समझदार और दान ...) – Malvolio

4

Set(a, b, c, d, e)(x) भी काम करता है। मैं पाठक के लिए एक अभ्यास के रूप में इसके कारणों को छोड़ दूंगा। :-)

0
class Ue (val i: Int) { 
    override def equals (other: Any) = other match { 
    case o: Ue => i == o.i 
    case _ => false } 
} 

val a = new Ue (4) 
// a: Ue = [email protected] 
val b = new Ue (4) 
// b: Ue = [email protected] (no identity) 
a == b 
// res110: Boolean = true (surprise?) 
a.equals (b) 
// res112: Boolean = true (expected) 
a.eq (b) 
// res113: Boolean = false (expected) 
List (a).contains (b)  
// res119: Boolean = true (surprise) 
List (a).exists (_ == b) 
// res120: Boolean = true (expected) 
List (a).exists (_ .eq (b)) 
// res121: Boolean = false (expected) 
संबंधित मुद्दे