2010-06-08 16 views
5

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

[Flags] 
enum Colours 
{ 
    Blue = 1, 
    Red = 2, 
    Green = 4 
} 

public static void Main() 
{ 
    var options = Colours.Blue | Colours.Red | Colours.Green; 
    var opts = options.ToString().Split(','); 
    var rand = new Random(); 
    var selected = opts[rand.Next(opts.Length)].Trim(); 
    var myEnum = Enum.Parse(typeof(Colours), selected); 
    Console.WriteLine(myEnum); 
    Console.ReadLine(); 
} 

उत्तर

8
var options = Colours.Blue | Colours.Green; 

var matching = Enum.GetValues(typeof(Colours)) 
        .Cast<Colours>() 
        .Where(c => (options & c) == c) // or use HasFlag in .NET4 
        .ToArray(); 

var myEnum = matching[new Random().Next(matching.Length)]; 
9

आप Enum.GetValues फोन इस तरह, enum के निर्धारित मान की एक सरणी प्राप्त करने के लिए कर सकते हैं:

var rand = new Random(); 

Colors[] allValues = (Colors[])Enum.GetValues(typeof(Colors)); 
Colors value = allValues[rand.Next(allValues.Length)]; 
+0

मैं के रूप में एक से परिभाषित किया गया केवल enum के एक सबसेट के एक यादृच्छिक मूल्य चाहते हैं थोड़ा सा संयोजन जैसे "ब्लू | रेड"। स्पष्ट नहीं होने के लिए खेद है। –

1

अगर मैं सही ढंग से समझ, सवाल एक झंडे enum मूल्य से एक यादृच्छिक enum मूल्य लौटने के बारे में है , झंडे enum से एक यादृच्छिक सदस्य वापस नहीं।

[Flags] 
    private enum Shot 
    { 
     Whisky = 1, 
     Absynthe = 2, 
     Pochin = 4, 
     BrainEraser = Whisky | Absynthe | Pochin 
    } 

    [Test] 
    public void Test() 
    { 
     Shot myCocktail = Shot.Absynthe | Shot.Whisky; 

     Shot randomShotInCocktail = GetRandomShotFromCocktail(myCocktail); 
    } 

    private static Shot GetRandomShotFromCocktail(Shot cocktail) 
    { 
     Random random = new Random(); 

     Shot[] cocktailShots = Enum.GetValues(typeof(Shot)). 
      Cast<Shot>(). 
      Where(x => cocktail.HasFlag(x)).ToArray(); 

     Shot randomShot = cocktailShots[random.Next(0, cocktailShots.Length)]; 

     return randomShot; 
    } 

संपादित

और स्पष्ट रूप से आप जांच करनी चाहिए कि enum कोई मान्य मान, उदा .:

Shot myCocktail = (Shot)666; 

है संपादित

सरलीकृत

+1

आप समस्या बताते हुए सही हैं। हालांकि मुझे लगता है कि आपका यादृच्छिक फ़ंक्शन मूल्यों को भी वितरण के साथ वापस नहीं करेगा। लूप के माध्यम से प्रत्येक मूल्य के लिए 50/50 मौके पर बाद के मूल्यों का चयन करने का कम मौका होता है? –

+0

मैं आपका पॉइंट देखता हूं। कड़ाई से बोलना अभी भी यादृच्छिक है और आपके प्रश्न का उत्तर देता है। मैंने इसे एक भी distro में अद्यतन किया है। देर हो चुकी है और मुझे यकीन है कि मैंने शायद भर लिया है! :) –

+0

और अब सरलीकृत। –

2

मैं एफ आपको थोड़ा कास्टिंग नहीं लगता है, और आपका enum अंतर्निहित int प्रकार का है, निम्नलिखित काम करेगा और तेज़ होगा।

var rand = new Random(); 
const int mask = (int)(Colours.Blue | Colours.Red | Colours.Green); 
return (Colours)(mask & (rand.Next(mask) + 1)); 

आप केवल चाहते हैं एक भी झंडा स्थापित किया जाना है, तो आप कर सकता है निम्नलिखित:

var rand = new Random(); 
return (Colours)(0x1 << (rand.Next(3))); 
+0

यदि "(int) allValues ​​& rand.Next()" का परिणाम शून्य है, और आपके पास शून्य नहीं है enum सदस्य, आप एक अवैध enum यानी (रंग) 0 मिलता है। –

+0

सच है। मुझे देखने दो कि क्या इसे ठीक किया जा सकता है ... – bbudge

+0

ठीक है, मुझे लगता है कि यह अब काम करता है। लेकिन यह थोड़ा गड़बड़ और कम स्पष्ट हो गया। केवल तभी उपयोगी जब प्रदर्शन एक गंभीर चिंता है। – bbudge

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