Exclude values from Random.Range()?

Yes, You simple use where statment in LINQ

   var list = Enumerable.Range(1, 20).Where(a => a < 6 || a > 8).ToArray();

Other way witout LINQ

        public IEnumerable RangeBetween()
        {
            foreach (var i in Enumerable.Range(1, 20))
            {
                if (i < 6 || i > 8)
                {
                    yield return i;
                }
            }
        }

EDIT: Now I see is not a strict C# question . It affect Unity and Random. But for complete answer I sugest You use code above with Enumerable.Range and next use this for generate the number:

list[Random.Next(list.Length)];

The best way to do this is to use your favourite generator to generate an integer n between 1 and 17 then transform using

if (n > 5){
    n += 3;
}

If you sample between 1 and 20 then discard values you can introduce statistical anomalies, particularly with low discrepancy sequences.


So you actually want 17 (20 - 3) different values

  [1..5] U [9..20]

and you can implement something like this:

  // Simplest, not thread-safe
  private static Random random = new Random();

  ...  

  int r = (r = random.Next(1, 17)) > 5
    ? r + 3
    : r;

In general (and complicated) case I suggest generating an array of all possible values and then take the item from it:

  int[] values = Enumerable
    .Range(1, 100) // [1..100], but
    .Where(item => item % 2 == 1) // Odd values only
    .Where(item => !(item >= 5 && item <= 15)) // with [5..15] range excluded
    //TODO: Add as many conditions via .Where(item => ...) as you want
    .ToArray();

  ...

  int r = values[random.Next(values.Length)];

Tags:

C#

Random

Unity3D