从Random.Range()中排除值?

Din*_*ovr 17 c# random unity-game-engine

如果您Random.Range()用于生成值,是否有任何方法可以排除范围内的某些值(例如:选择1到20之间的数字,但不是6到8之间的数字)?

Bat*_*eba 12

执行此操作的最佳方法是使用您喜欢的生成器生成n1到17之间的整数,然后使用

if (n > 5){
    n += 3;
}
Run Code Online (Sandbox Code Playgroud)

如果您在1到20之间采样然后丢弃值,则可能会引入统计异常.(例如,如果您的随机数生成器是线性同余生成器,则您的方差将太高:尝试并查看.)


Dmi*_*nko 10

所以你实际上想要17(20 - 3)不同的值

  [1..5] U [9..20]
Run Code Online (Sandbox Code Playgroud)

你可以实现这样的事情:

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

  ...  

  int r = (r = random.Next(1, 17)) > 5
    ? r + 3
    : r;
Run Code Online (Sandbox Code Playgroud)

在一般(和复杂)的情况下,我建议生成一个包含所有可能值的数组,然后从中获取项目:

  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)];
Run Code Online (Sandbox Code Playgroud)


blo*_*net 5

是的,你where在LINQ中使用简单的语句

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

其他方式没有LINQ

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

编辑:现在我看到的不是一个严格的C#问题.它影响UnityRandom.但是对于完整的答案我sugest你使用上面的代码, Enumerable.Range然后使用它来生成数字:

list[Random.Next(list.Length)];
Run Code Online (Sandbox Code Playgroud)