2012-03-12 11 views
11

मेरे प्रश्न का मुख्य हिस्सा छोड़ना है। मैं एक एनम प्रकार का उपयोग करने की योजना बना रहा हूं जिसमें लगभग 20 तत्व हैं। मैं इस सेट के माध्यम से फिर से शुरू करना चाहता हूं लेकिन हर बार एक तत्व या दो छोड़ने की जरूरत है। क्या छोड़ना है अग्रिम में जाना जाता है। एक तुलनात्मक उदाहरण enum प्रकार है जिसमें वर्णमाला के सभी अक्षरों होते हैं, और जब पुनरावृत्त होते हैं, तो मैं सभी स्वरों को छोड़ना चाहता हूं।कुछ मूल्यों को छोड़ते समय enum प्रकार के माध्यम से फिर से कैसे करें?

मुझे एक सुरुचिपूर्ण/कुशल तरीके से पुनरावृत्ति को कैसे कोड करना चाहिए? क्या मुझे स्वरों से युक्त तत्वों का एक अलग सेट बनाना चाहिए? मेरे पास दिखाने के लिए कोई कोड नहीं है क्योंकि मैं सिर्फ समस्या के बारे में सोच रहा हूं।

उत्तर

27
var query = Enum.GetValues(typeof(MyEnum)) 
    .Cast<MyEnum>() 
    .Except(new MyEnum[] { MyEnum.A, MyEnum.E }); 
foreach (MyEnum item in query) { 
    ... 
} 

आपको LINQ का जादू प्राप्त करने के लिए कास्ट करने के लिए की जरूरत है। Except अकेले ऐसा नहीं करेगा।


अद्यतन:

मैं एक विचार आया। आप FlagsAttribute के साथ enum को परिभाषित कर सकते हैं और नियमित मानों को 2 की शक्तियों के रूप में परिभाषित कर सकते हैं, जो बिटवाई शिफ्ट बाएं ऑपरेटर << के साथ सबसे आसानी से हासिल किया जाता है। सी # 7.0 से शुरू, आप 0b_0000_0000_0010_0000 जैसे बाइनरी अक्षरों का भी उपयोग कर सकते हैं। फिर नए मान बनाने के लिए मौजूदा मानों को जोड़ना संभव है।

[Flags] 
enum MyEnum 
{ 
    None = 0, 
    A = 1 << 0, 
    B = 1 << 1, 
    C = 1 << 2, 
    D = 1 << 3, 
    E = 1 << 4, 
    ... 
    X = 1 << 23, 
    Y = 1 << 24, 
    Z = 1 << 25, 
    Vowels = A | E | I | O | U 
} 

अब आप इस

IEnumerable<MyEnum> query = Enum.GetValues(typeof(MyEnum)) 
    .Cast<MyEnum>() 
    .Where(x => (x & MyEnum.Vowels) == MyEnum.None); 
foreach (MyEnum item in query) { 
    ... 
} 

पहला समाधान से अधिक लाभ है जैसी क्वेरी तैयार कर सकते हैं, जिन्हें आप एक बिटवाइज़ और आपरेशन के साथ परीक्षण कर सकते हैं।

आप दो की 32 शक्तियों को परिभाषित कर सकते हैं। यदि आपको और अधिक चाहिए, तो आप एनम के आधार प्रकार को long के रूप में परिभाषित कर सकते हैं और 64 ध्वज मानों (साथ ही मौजूदा ध्वज मूल्यों के संयोजन) का उपयोग कर सकते हैं।

[Flags] 
enum MyEnum : long 
{ 
    ... 
} 
+0

यह शायद सबसे पूरा उत्तर है। यहां से सबसे आसान बात यह है कि एनम्स के विभिन्न संग्रह निर्दिष्ट करना चाहते हैं जिन्हें आप छोड़ना चाहते हैं, इस तरह आप उन स्किप संग्रहों को सहेज सकते हैं और जो कुछ भी आप चाहते हैं उसे छोड़ सकते हैं। – SPFiredrake

+0

हां, और आप विभिन्न प्रश्न भी रख सकते हैं। –

+1

मैंने केवल थोड़ा सा उपयोग करके और परीक्षण करने के लिए एक और समाधान जोड़ा। असाधारण मूल्यों के लिए इसे किसी भी सरणी या हैशसेट की आवश्यकता नहीं है। कृपया मेरा अपडेट देखें। –

1

मैं स्वरों से युक्त तत्वों का एक अलग सेट बनाउंगा, और फिर LINQ का उपयोग करके दो सेटों के बीच सेट अंतर लेंगे।

int[] vowels = {Letters.A, Letters.E, Letters.I, Letters.O, Letters.U}; 
IEnumerable<int> consonant = Enum.GetValues(typeof(Letters)).Except(vowels); 
foreach (int consonant in consonants) 
{ 
    // Do something with each consonant 
} 
1

मैं शायद सिर्फ LINQ का उपयोग करेंगे - Enum.GetValues का उपयोग (या Unconstrained Melody का उपयोग करें - एक प्रकार सुरक्षित सामान्य enum/प्रतिनिधि पुस्तकालय मैंने लिखा) सभी मूल्यों को प्राप्त करने के लिए, तो व्यक्त जो रखने के लिए महत्व देता है/एक के माध्यम से छोड़ Where खंड।

यदि आप केवल विशिष्ट मान छोड़ रहे हैं, तो HashSet या ऐसा कुछ उपयोगी हो सकता है (यदि आप केवल एक को छोड़ रहे हैं तो इसके लायक नहीं) - यदि आप किसी शर्त के आधार पर छोड़ रहे हैं, तो एक पूर्ण -बाउन predicate के लिए बुलाया जाता है।

उदाहरण के लिए:

public static IEnumerable<T> AllBut(T skipped) where T : struct 
{ 
    IEqualityComparer<T> comparer = EqualityComparer<T>.Default; 
    return AllBut<T>(t => !comparer.Equals(skipped, t)); 
} 

public static IEnumerable<T> AllBut(Func<T, bool> skipPredicate) where T : struct 
{ 
    IEqualityComparer<T> comparer = EqualityComparer<T>.Default; 
    return Enum.GetValues(typeof(T)) 
       .Cast<T>() 
       .Where(t => skipPredicate(t)); 
} 
संबंधित मुद्दे