2010-10-11 13 views
59

कथन अगर इसे लिखने का कोई आसान तरीका है?यदि एकाधिक मानों से मेल खाने वाले बयान

if (value==1 || value==2)

उदाहरण के लिए ... एसक्यूएल में आप where value in (1,2) बजाय where value=1 or value=2 कह सकते हैं।

मैं कुछ है कि किसी भी बुनियादी प्रकार ... स्ट्रिंग, पूर्णांक के साथ काम करेगा, आदि के लिए देख रहा हूँ

+2

आसान व्यक्तिगत प्राथमिकता है। निजी तौर पर, मुझे नहीं लगता कि यह 'value == 1 || से कहीं अधिक आसान हो जाता है मान == 2'। –

+1

@ जोएल: यह आसान है, लेकिन किसी ऐसे व्यक्ति के लिए सहज नहीं है जो कहता है "मैं इसे 1 या 2 होना चाहता हूं"। जैसा कि यह पता चला है, ऐसी भाषाएं हैं जो इस वाक्यविन्यास को ठीक से लागू करती हैं; आईबीआई की फोकस क्वेरी लैनागुएज, एक के लिए। –

+0

@ स्टेवन सूडिट - उस संदर्भ में "अंतर्ज्ञानी" व्यक्तिगत वरीयता के लिए उबलता है। –

उत्तर

86

कैसे के बारे में:

public static bool In<T>(this T obj, params T[] args) 
{ 
    return args.Contains(obj); 
} 

:

if (new[] {1, 2}.Contains(value)) 

हालांकि यह :)

एक हैक है या यदि आप अपने खुद के विस्तार विधि बनाने से परहेज नहीं करते, तो आपको निम्न बना सकते हैं और आप इसे इस तरह उपयोग कर सकते हैं:

if (1.In(1, 2)) 

:)

+7

मुझे नहीं लगता कि पहला सुझाव वास्तव में एक हैक है, यह मेरे लिए काफी सुरुचिपूर्ण लगता है, खासकर यदि यह पृष्ठभूमि में कोड है जो ज्यादातर लोग 'IsOneOfACertainType (TypeToCheck) के माध्यम से कॉल करते हैं; उदाहरण के लिए – Coops

+2

भूलना न भूलें 'कंटेनर' का उपयोग करने के लिए 'System.Linq;' का उपयोग करना शामिल है। –

+1

वह * वास्तव में * पाइथन की तरह दिखता है! – Panzercrisis

6

आप एक सूची है, तो आप, .Contains (yourObject) का उपयोग कर सकते अगर आप सिर्फ रहे हैं इसे मौजूदा (जैसे एक) की तलाश में है। अन्यथा लिंकक को देखो। कोई() एक्सटेंशन विधि।

3

आम तौर पर, नहीं।

हां, ऐसे मामले हैं जहां सूची Array या List में है, लेकिन यह सामान्य मामला नहीं है।

22

क्या आप यह देख रहे हैं?

if (new int[] { 1, 2, 3, 4, 5 }.Contains(value)) 
5

Linq का उपयोग करना,

if(new int[] {1, 2}.Contains(value))

लेकिन मुझे लगता है कि करने के लिए तेजी से होता है अपने मूल अगर होगा।

+0

इन दोनों के बीच प्रदर्शन अंतर लगभग निश्चित रूप से अप्रासंगिक है। मूल अधिक पठनीय और मूर्खतापूर्ण है। 'निश्चित रूप से लिखना संभव है' रेंज (0, 10)। टॉलिस्ट()। ForEach (x => कंसोल। राइटलाइन (एक्स)); 'के बजाय' (int i = 0; i <10; i ++) { Console.WriteLine (i); } 'लेकिन यह सिर्फ लोगों को पेश करने जा रहा है। "कोई भी कभी लिखता है कि एक समूह बनें।" – jason

+0

@ जेसन - मैं मानता हूं कि अगर मैंने उत्पादन कोड में जो लिखा है, तो मुझे पिस कर दिया जाएगा। "इसे ठीक से पालन करें" की तुलना में "इसे करने का तरीका समझाने के लिए एक पंक्ति" थी। वास्तव में, मैं स्विच स्टेटमेंट का सुझाव देने वाले लोगों से सहमत हूं। –

33

एक और अधिक जटिल तरीके से :) कि SQL के 'में emulates:

public static class Ext {  
    public static bool In<T>(this T t,params T[] values){ 
     foreach (T value in values) { 
      if (t.Equals(value)) { 
       return true; 
      } 
     } 
     return false; 
    } 
} 

if (value.In(1,2)) { 
    // ... 
} 

लेकिन मानक तरीका के लिए जाते हैं, इसे और अधिक पठनीय है।

संपादित: एक बेहतर समाधान, @ करने के लिए कोबी के सुझाव अनुसार:

public static class Ext {  
    public static bool In<T>(this T t,params T[] values){ 
     return values.Contains(t); 
    } 
} 
+0

को रिटर्न प्रकार की आवश्यकता है, लेकिन एक एक्सटेंशन विधि है जो मैं सुझाव दे रहा था साथ ही –

+1

@ डैनियल: हाँ, तय, धन्यवाद :) –

+0

+1। अच्छा समाधान, बस मेरी तरह, लेकिन जेनेरिक का उपयोग कर आपका। मैं तुम्हारी जगह अपने साथ बदल दूंगा :) – goenning

1

एक्सटेंशन के तरीके का उपयोग करना:

public static class ObjectExtension 
{ 
    public static bool In(this object obj, params object[] objects) 
    { 
     if (objects == null || obj == null) 
      return false; 
     object found = objects.FirstOrDefault(o => o.GetType().Equals(obj.GetType()) && o.Equals(obj)); 
     return (found != null); 
    } 
} 

अब आप यह कर सकते हैं:

string role= "Admin"; 
if (role.In("Admin", "Director")) 
{ 
    ... 
} 
0
public static bool EqualsAny<T>(IEquatable<T> value, params T[] possibleMatches) { 
    foreach (T t in possibleMatches) { 
     if (value.Equals(t)) 
      return true; 
    } 
    return false; 
} 
public static bool EqualsAny<T>(IEquatable<T> value, IEnumerable<T> possibleMatches) { 
    foreach (T t in possibleMatches) { 
     if (value.Equals(t)) 
      return true; 
    } 
    return false; 
} 
5

वैकल्पिक रूप से, और यह आप और अधिक लचीलापन देना होगा अगर 1 या 2 भविष्य में अन्य की तुलना में मूल्यों के लिए परीक्षण, एक स्विच बयान

switch(value) 
{ 
case 1: 
case 2: 
    return true; 
default: 
    return false 
} 
+0

मैं "वैकल्पिक रूप से" भी नहीं कहूंगा, यह उदाहरण के लिए दिए गए एक सूची के साथ एसक्यूएल उपयोग के लिए निकटतम समानता है ('कंटेनर()' आदि। सबकुरी के परिणामों के विरुद्ध आईएन के साथ)। –

1

आसान व्यक्तिपरक है उपयोग करने के लिए है, लेकिन शायद स्विच बयान आसान होगा? आपको चर को दोहराना नहीं है, इसलिए लाइन पर अधिक मूल्य फिट हो सकते हैं, और कई तुलनाओं वाली एक पंक्ति अगर कथन का उपयोग कर समकक्ष की तुलना में अधिक सुगम है।

1

एक extensionmethod की तरह इस यह करना होगा ...

public static bool In<T>(this T item, params T[] items) 
{ 
    return items.Contains(item); 
} 

इस तरह यह प्रयोग करें:

Console.WriteLine(1.In(1,2,3)); 
Console.WriteLine("a".In("a", "b")); 
1

vb.net या सी # कि सबसे तेजी से सामान्य दृष्टिकोण एक तुलना करने के लिए मैं उम्मीद करेंगे में अलग-अलग नामित वस्तुओं की किसी भी उचित संख्या के विरुद्ध परिवर्तनीय (उदाहरण के लिए संग्रह में सभी चीजों के विपरीत) प्रत्येक ऑब्जेक्ट की तुलना तुलनात्मक रूप से तुलना करने के लिए किया जाएगा जैसा आपने किया है। संग्रह का एक उदाहरण बनाना निश्चित रूप से संभव है और देखें कि इसमें ऑब्जेक्ट है या नहीं, और ऐसा करने से वस्तु को सभी वस्तुओं के विरुद्ध तुलना करने की तुलना में अधिक अभिव्यक्तिपूर्ण हो सकता है, लेकिन जब तक कि कोई ऐसा निर्माण नहीं करता जो संकलक स्पष्ट रूप से पहचान सके, ऐसे कोड व्यक्तिगत रूप से व्यक्तिगत तुलना करने से लगभग निश्चित रूप से धीमा हो जाएगा। मैं गति के बारे में चिंता नहीं करता अगर कोड अपनी प्रकृति से प्रति सेकंड कुछ सौ गुना दौड़ता है, लेकिन मैं उस शर्त से सावधान रहूंगा जो मूल रूप से इरादे से अधिक बार चलाया जाता है।

एक वैकल्पिक दृष्टिकोण, यदि कोई चर एक गणना प्रकार की तरह कुछ है, तो बिटमास्क के उपयोग की अनुमति देने के लिए दो-दो गणना मानों का चयन करना है। यदि गणना प्रकार में 32 या कम मान्य मान हैं (उदाहरण के लिए हैरी = 1, रॉन = 2, हर्मियोन = 4, गिनी = 8, नेविल = 16) एक व्यक्ति उन्हें एक पूर्णांक में स्टोर कर सकता है और एक बार में कई बिट्स की जांच कर सकता है ऑपरेशन ((अगर (0 यह(हैरी | रॉन | नेविल | बीट्रिक्स))! = 0)/* कुछ करें * /। यह तेज़ कोड की अनुमति देगा, लेकिन यह संख्याओं की एक छोटी संख्या के साथ गणना तक ही सीमित है।

कुछ और अधिक शक्तिशाली दृष्टिकोण, लेकिन देखभाल के साथ उपयोग किया जाना चाहिए, किसी चीज के गुणों को इंगित करने के लिए मूल्य के कुछ बिट्स का उपयोग करना है, जबकि अन्य बिट्स आइटम की पहचान करते हैं। उदाहरण के लिए, बिट 30 इंगित कर सकता है कि एक चरित्र पुरुष है , बिट 2 दोस्त-ऑफ-हैरी इत्यादि को इंगित कर सकता है, जबकि निचले बिट वर्णों के बीच अंतर करते हैं। यह दृष्टिकोण उन पात्रों को जोड़ने की अनुमति देगा जो दोस्त के हैंरी हो सकते हैं या नहीं, बिना कोड की आवश्यकता के कोड बदलने के लिए दोस्त हैरी। ऐसा करने के साथ एक चेतावनी यह है कि किसी को गणित स्थिरांक के बीच अंतर करना चाहिए जिसका उपयोग गणना गणना मूल्य के लिए किया जाता है, और जो इसे परीक्षण करने के लिए उपयोग किए जाते हैं। उदाहरण के लिए, हैरी को इंगित करने के लिए एक चर सेट करने के लिए, कोई इसे 0x60000001 पर सेट करना चाहता है, लेकिन यह देखने के लिए कि कोई चर है आईएस हैरी, इसे 0x00000001 के साथ थोड़ा-परीक्षण करना चाहिए।

एक और दृष्टिकोण, जो उपयोगी हो सकता है यदि संभावित मूल्यों की कुल संख्या मध्यम है (उदाहरण के लिए 16-16,000 या उससे अधिक) प्रत्येक मान से जुड़े झंडे की एक सरणी है।तब कोई कुछ "कोड (" (चरित्र गुण [theCharacter] & chracterAttribute.Male)! = 0) "। यह दृष्टिकोण सबसे अच्छा काम करेगा जब वर्णों की संख्या काफी छोटी है। यदि सरणी बहुत बड़ी है, तो कैश मिस धीमा हो सकता है आप टी > मूल्यों की नियत सूची में एक मूल्य में कई बार, HashSet < खोज करते हैं का कहना है कि पात्रों की एक छोटी संख्या के खिलाफ परीक्षण करने के लिए कोड नीचे व्यक्तिगत रूप से तेजी से होगा।

4

, इस्तेमाल किया जाना चाहिए यहां तक ​​कि बस के लिए हैशसेट के रूप में यह बाइनरी खोज पेड़ में डेटा स्टोर/खोजता है।

HashSet<int> nums = new HashSet<int> { 1, 2, 3, 4, 5 }; 
// .... 
if (nums.Contains(value)) 
0

मुझे एक ही समस्या थी टी स्विच स्विच स्विच (एक मूल्य जिसे आप चालू कर रहे हैं) { केस 1: कोड जो आप करना चाहते हैं; केस 2: वह कोड जो आप करना चाहते हैं; डिफ़ॉल्ट: एक मान }

संबंधित मुद्दे