मैं एन्यूमरेशन से यादृच्छिक मान का चयन कैसे करूं?


171

C # में एक मनमानी गणना को देखते हुए, मैं एक यादृच्छिक मूल्य कैसे चुनूं?

(मुझे एसओ पर यह बहुत बुनियादी सवाल नहीं मिला। मैं किसी के संदर्भ में एक मिनट में अपना जवाब पोस्ट करूंगा, लेकिन कृपया अपना खुद का उत्तर पोस्ट करने के लिए स्वतंत्र महसूस करें।)

जवाबों:


282
Array values = Enum.GetValues(typeof(Bar));
Random random = new Random();
Bar randomBar = (Bar)values.GetValue(random.Next(values.Length));

40
सुनिश्चित करें कि आप randomएक तंग लूप में फिर से बनाए नहीं रखते हैं - अन्यथा आप समान मूल्य प्राप्त करते रहेंगे।
ChrisF

1
क्या यह यादृच्छिक होना चाहिए। पाठ (मान। गति -1)?
यूरिडियम

7
@uriDium नहीं, यह तर्क निर्दिष्ट करता है कि कौन सा मान सबसे पहले लौटाया जाना है (यानी अधिकतम शून्य 1 )
mafu

values.Length - 1
Bojidar Stanchev

DarCDititrov IMO @ChrisF द्वारा पहली टिप्पणी क्रिस के लिए क्रेडिट के साथ जवाब के अंदर एक नोट होना चाहिए।
मेथम-ɯɐɥʇʎɐɯ

62

सभी मानों की एक सरणी को पुनः प्राप्त करने के लिए Enum.GetValues ​​का उपयोग करें। फिर एक यादृच्छिक सरणी आइटम चुनें।

static Random _R = new Random ();
static T RandomEnumValue<T> ()
{
    var v = Enum.GetValues (typeof (T));
    return (T) v.GetValue (_R.Next(v.Length));
}

परीक्षा:

for (int i = 0; i < 10; i++) {
    var value = RandomEnumValue<System.DayOfWeek> ();
    Console.WriteLine (value.ToString ());
}

->

Tuesday
Saturday
Wednesday
Monday
Friday
Saturday
Saturday
Saturday
Friday
Wednesday

5

आप ऐसा कर सकते हैं:

var rnd = new Random();
return (MyEnum) rnd.Next(Enum.GetNames(typeof(MyEnum)).Length);

सरणियों को संग्रहीत करने की आवश्यकता नहीं है


GetNamesएक सरणी देता है।
नाथन तुग्गी

मेरा मतलब था कि आपको इसे स्टोर करने की आवश्यकता नहीं है। मेरा बुरा
ब्रेनो एंजेलोटी

अगर कोई इसे लूप में कर रहा है तो वे इसे सरणी में कैशिंग करने के बजाय हर बार गेटनेम्स को कॉल करेंगे। यह उनके कोड को धीमा कर देगा, इसलिए मुझे नहीं दिखता कि यहां आपका क्या योगदान है?
बोजिडार स्टेंचव

@BojidarStanchev अगर , मेरे मामले में यह अद्भुत काम करता है, धन्यवाद ब्रेनो :)
जैको टोरस

4

यहां Extension Methodउपयोग के रूप में एक वैकल्पिक संस्करण है LINQ

using System;
using System.Linq;

public static class EnumExtensions
{
    public static Enum GetRandomEnumValue(this Type t)
    {
        return Enum.GetValues(t)          // get values from Type provided
            .OfType<Enum>()               // casts to Enum
            .OrderBy(e => Guid.NewGuid()) // mess with order of results
            .FirstOrDefault();            // take first item in result
    }
}

public static class Program
{
    public enum SomeEnum
    {
        One = 1,
        Two = 2,
        Three = 3,
        Four = 4
    }

    public static void Main()
    {
        for(int i=0; i < 10; i++)
        {
            Console.WriteLine(typeof(SomeEnum).GetRandomEnumValue());
        }
    }           
}

दो
एक
चार
चार
चार
तीन
दो
चार
एक
तीन


2

पुकार Enum.GetValues; यह एक सरणी देता है जो आपके एनम के लिए सभी संभावित मूल्यों का प्रतिनिधित्व करता है। इस सरणी से एक यादृच्छिक आइटम चुनें। उस वस्तु को मूल एनम प्रकार पर वापस कास्ट करें।


2

यहाँ इसके लिए एक सामान्य कार्य है। उच्च आवृत्ति कोड के बाहर RNG निर्माण रखें।

public static Random RNG = new Random();

public static T RandomEnum<T>()
{  
    Type type = typeof(T);
    Array values = Enum.GetValues(type);
    lock(RNG)
    {
        object value= values.GetValue(RNG.Next(values.Length));
        return (T)Convert.ChangeType(value, type);
    }
}

उपयोग उदाहरण:

System.Windows.Forms.Keys randomKey = RandomEnum<System.Windows.Forms.Keys>();

एक स्थैतिक विधि जो थ्रेडसेफ़ नहीं है, बहुत खतरनाक है।
कोडइन्चोअस

@CodesInChaos तुम सही हो। Random.Next () थ्रेडसेफ़ नहीं है और यह टूटने पर जीरो वापस करना शुरू कर देगा। मैंने इस जानकारी के आधार पर अपना उत्तर अपडेट कर दिया है।
व्होल

1

व्यक्तिगत रूप से, मैं विस्तार विधियों का प्रशंसक हूं, इसलिए मैं इस तरह से कुछ का उपयोग करूंगा (जबकि वास्तव में विस्तार नहीं है, यह समान दिखता है):

public enum Options {
    Zero,
    One,
    Two,
    Three,
    Four,
    Five
}

public static class RandomEnum {
    private static Random _Random = new Random(Environment.TickCount);

    public static T Of<T>() {
        if (!typeof(T).IsEnum)
            throw new InvalidOperationException("Must use Enum type");

        Array enumValues = Enum.GetValues(typeof(T));
        return (T)enumValues.GetValue(_Random.Next(enumValues.Length));
    }
}

[TestClass]
public class RandomTests {
    [TestMethod]
    public void TestMethod1() {
        Options option;
        for (int i = 0; i < 10; ++i) {
            option = RandomEnum.Of<Options>();
            Console.WriteLine(option);
        }
    }

}

1
C # 7.3 के अनुसार, आप अपने सामान्य प्रकार को public static T Of<T>() where T : Enum एनम
nitzel

0

रैंडम क्लास एक्सटेंशन के रूप में अनुकूलित:

public static class RandomExtensions
{   
    public static T NextEnum<T>(this Random random)
    {
        var values = Enum.GetValues(typeof(T));
        return (T)values.GetValue(random.Next(values.Length));
    }
}

उपयोग का उदाहरण:

var random = new Random();
var myEnumRandom = random.NextEnum<MyEnum>();

0

आप एक यादृच्छिक मूल्य भी डाल सकते हैं:

using System;

enum Test {
  Value1,
  Value2,
  Value3
}

class Program {
  public static void Main (string[] args) {
    var max = Enum.GetValues(typeof(Test)).Length;
    var value = (Test)new Random().Next(0, max - 1);
    Console.WriteLine(value);
  }
}

लेकिन आपको इस लाइब्रेरी के एक बेहतर रैंडमाइज़र का उपयोग करना चाहिए ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.