# Exclude values from Random.Range()?

12,992

## Solution 1

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.

## Solution 2

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)];
``````

## Solution 3

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)];
``````

## Solution 4

Another way is to make an array of the valid return values and then randomly select one:

``````void Main()
{
var rng = new Random();
var validValues = Enumerable.Range(1, 20).Except(new int[] {6, 7, 8}).ToArray();

for (int i = 0; i < 25; i++)
{
Console.Write(validValues[rng.Next(0, validValues.Length)]);
Console.Write(" ");
}
}
``````

EDIT: Oops! Just noticed this was for Unity3D so this example might not be appropriate. It works using the standard `Random` class, though.

Share:
12,992

Author by

### Dinovr

Updated on September 14, 2022

• Dinovr 4 months

If you are using `Random.Range()` to generate values, is there any way to exclude some values within the range (for example: pick a number between 1 and 20, but not 6 through 8)?

• Bathsheba
I've added the random tag to introduce this question to the many random number experts on this site, and to give my answer some credibility.
• Andrey Korneyev
You can write your own method to check if generated number falls into excluded ranges and in this case re-generate it.
• Programmer over 6 years
This is for game engine. If you can avoid linq, avoid it. It allocates memory and some functions wont work in iOS.
• blogprogramisty.net over 6 years
@Programmer Avoid lambda expression too?
• Bathsheba over 6 years
Plus one, this is statistically correct; I'm trusting that the assignment on the conditional test to a variable you've defined on the left of the assignment is well-defined in C#!
• Programmer over 6 years
I wouldn't say that. I mean if he calling that code most of the time, he should avoid it.
• Ignacio over 6 years
I think that using this method there is a chance (really small one, but still) that the program enters in an infinite loop... if you always get a number between 6 and 8.
• Programmer over 6 years
I feel like commenting on this one. This is a great way to freeze your game. @Ignacio You are right. This has happened to me before. No while loop while generating random number in Unity.
• Isaak Eriksson over 6 years
@Programmer LINQ works fine on iOS if you use Lists instead of arrays. It is a great asset for abstracting the complications of loops and lists. I think the reason why it works only with Lists on iOS because LINQ doesn't use `IEnumerable` (which has problems on iOS) on Lists whereas on arrays it does. Interesting.
• Ignacio over 6 years
@Programmer, not just in Unity, It can freeze any program
• Programmer over 6 years
@Ignacio Good to know that.
• Programmer over 6 years
@MyIsaak Yes it works with List. It's not working because of AOT features not available on iOS. Although I use few linq functions from it only when necessary. Still, the first code in his answer will still allocate memory just to generate random number....Not worth the sacrifice.
• Benjamin Gruenbaum over 6 years
Uh, it really can't freeze a program. Computers rely on being able to generate random numbers and use random processes everywhere - things like the internet and its protocols rely on that - there is a chance that a packet will drop and never arrive but statistically this never happens. If you run this program on a computer since the start of the universe until now it would not ever get stuck - it's easy to prove that on a uniform probability (or any probability with a non-zero chance for a number not between 6 and 8 to appear) that it would likely not get stuck for over a second ever.
• Everts over 6 years
Unity3D provides a Random class and most users rely on that one. Also, Linq is not so recommended in Unity for internal reason (FullAOT on iOS) which makes some of its functionalities not always work.