1

Is there an easy way for me to select a random bit value from my enum variable?
For example:

[System.Flags]
public enum Direction{
    None = 0,
    Up = 1,
    Down = 2, 
    Left = 4, 
    Right = 8,
    All = ~None
}

public Direction someDir = Direction.Up | Direction.Down;

I would want to select a random positive bit value from someDir so that I could only have Direction.Up or Direction.Down?

Stephan Bauer
  • 9,120
  • 5
  • 36
  • 58
Alec Gamble
  • 441
  • 3
  • 6
  • 16
  • var gen = new Random(); var upOrDown = (Direction ) (gen.Next(1)+1); – mukh1n Mar 21 '17 at 10:03
  • well I want to get a new direction which is one of the values in the `someDir` variable so that I would ultimately get Direction.Up or Direction.Down, or one of whatever values are stored in someDir. – Alec Gamble Mar 21 '17 at 10:05

2 Answers2

2

You should use an array:

Direction validDirections = new[] { Direction.Up, Direction.Down };

and then:

Random rnd = new Random();
Direction selectedDirection = validDirections[rnd.Next(validDirections.Length)];

(remember to reuse the same Random rnd and not recreate it every time)

If you really really want to have a single Direction variable, then you could split it to a List<Direction>:

Direction someDir = Direction.Up | Direction.Down;

var someDir2 = new List<Direction>();

foreach (Direction dir in Enum.GetValues(typeof(Direction)))
{
    if (someDir.HasFlag(dir))
    {
        someDir2.Add(dir);
    }
}

Random rnd = new Random();
Direction selectedDirection = someDir2[rnd.Next(someDir2.Count)];

(see Most efficient way to parse a flagged enum to a list and the various comments about using HasFlag)

Community
  • 1
  • 1
xanatos
  • 109,618
  • 12
  • 197
  • 280
  • okay thanks :) I mean neither of these feel like the clean implementation that I wanted but I can understand the limitations and will work with this. Thanks a lot! :) – Alec Gamble Mar 21 '17 at 10:24
0

I was looking the same thing, I didn't find it (sorry if it's published somewhere else), so I came up with this...

Example enum:

[Flags]
public enum DayOfWeek
{
    Sunday = 1 << 0,
    Monday = 1 << 1,
    Tuesday = 1 << 2,
    Wednesday = 1 << 3,
    Thursday = 1 << 4,
    Friday = 1 << 5,
    Saturday = 1 << 6
};

Extension:

static class EnumerationExtension
{
    
    private static System.Random R { get; set; } = new System.Random();

    public static Enum Random(this Enum enumeration)
    {
        var type = enumeration.GetType();
        var strs = enumeration.ToString().Split(", ");
        var index = R.Next(strs.Length);
        return (Enum)Enum.Parse(type, strs[index]);
    }

}

Usage, let's pick Monday, Wednesday and Friday:

var mwf = DayOfWeek.Monday | DayOfWeek.Wednesday | DayOfWeek.Friday;
Console.WriteLine($"Chosen days: {mwf}");
        
for (int i = 0; i < 10; ++i)
    Console.WriteLine($"Random day: {mwf.Random()}");

Output, as you can see it only picks 1 of the 3 previous days:

Chosen days: Monday, Wednesday, Friday
Random day: Friday
Random day: Wednesday
Random day: Monday
Random day: Wednesday
Random day: Monday
Random day: Monday
Random day: Wednesday
Random day: Friday
Random day: Monday
Random day: Monday

I leave the fiddle to test

It's nothing fancy, but I hope to help people like me that are not "seniors" in C#

fmj.SO
  • 9
  • 7