如何在C#中从数组中获取随机值

33

可能是重复问题:
如何访问列表中的随机元素

我有一个包含数字的数组,想要从中获取随机元素。例如:{0,1,4,6,8,2}。我想选择数字6并将其放入另一个数组中,新数组将变为{6,....}。

我使用random.next(0, array.length),但这仅会给出数组长度范围内的随机数,而我需要随机选取数组中的元素。

for (int i = 0; i < caminohormiga.Length; i++ )
{
    if (caminohormiga[i] == 0)
    {
        continue;
    }

    for (int j = 0; j < caminohormiga.Length; j++)
    {
        if (caminohormiga[j] == caminohormiga[i] && i != j)
        {
            caminohormiga[j] = 0;
        }
    }
}

for (int i = 0; i < caminohormiga.Length; i++)
{
   int start2 = random.Next(0, caminohormiga.Length);
   Console.Write(start2);
}

return caminohormiga;

1
通过简单的随机选择,您将获得重复项。您想返回caminohormiga的洗牌副本吗? - H H
1
@shebystian 是否适用于重复项? - exexzian
你想要对你的 caminohormiga 数组进行洗牌(shuffle)还是旋转(rotate)操作? - Alexander Balte
如果您不想要重复项,并且假设输出更好使用shuffle而不是检查重复项,这需要花费时间。 - exexzian
如果您可以接受重复项,请查看已接受的答案。如果您想要无重复项的随机排列,请查看此答案。 - Seth Flowers
6个回答

50

我使用random.next(0, array.length)方法,但它会返回长度内的随机数,而我需要获得随机数组中的数字。

请将random.next(0, array.length)的返回值用作索引,以从array中获取值。

 Random random = new Random();
 int start2 = random.Next(0, caminohormiga.Length);
 Console.Write(caminohormiga[start2]);

1
谢谢!代码终于可以运行了,但是数字重复了,有什么办法可以避免重复吗? - Shebystian
1
是的,在循环中从数组中删除元素。 - Tilak
为避免重复数字,请使用 IEnumerable.OrderBy(n => Guid.NewGuid())。请参阅我的答案 - Seth Flowers
1
获取重复项可能是由于 Random 类的行为方式造成的。 尽量不要在每次获取随机数时实例化 Random,保持单个实例。 - SHM
使用堆栈来避免逻辑错误。 使用stack.push('abc')方法将值插入堆栈中。 在使用stack.pop()之前,使用stack.Peek()方法获取堆栈顶部的值作为堆栈对象。根据需要将其转换为字符串或整数,取得值后再使用stack.pop()。您将永远无法从堆栈中获取到已弹出的值,因为它已经被使用过了。 - undefined

33

洗牌

int[] numbers = new [] {0, 1, 4, 6, 8, 2};
int[] shuffled = numbers.OrderBy(n => Guid.NewGuid()).ToArray();

迄今为止最佳解决方案。 - undefined

5
你只需要将随机数用作数组的引用即可:
var arr1 = new[]{1,2,3,4,5,6}
var rndMember = arr1[random.Next(arr1.Length)];

3

我注意到在评论中您不希望有重复,因此您希望数字类似于一副牌被“洗牌”。

我会使用 List<> 作为源项目,随机地从中选取并将它们 推入 到一个 Stack<> 中,以创建数字的牌组。

这是一个示例:

private static Stack<T> CreateShuffledDeck<T>(IEnumerable<T> values)
{
  var rand = new Random();

  var list = new List<T>(values);
  var stack = new Stack<T>();

  while(list.Count > 0)
  {
    // Get the next item at random.
    var index = rand.Next(0, list.Count);
    var item = list[index];

    // Remove the item from the list and push it to the top of the deck.
    list.RemoveAt(index);
    stack.Push(item);
  }

  return stack;
}

所以,接下来:
var numbers = new int[] {0, 1, 4, 6, 8, 2};
var deck = CreateShuffledDeck(numbers);

while(deck.Count > 0)
{
  var number = deck.Pop();
  Console.WriteLine(number.ToString());
}

rand.Next(0, list.Count); 应该改为 rand.Next(0, list.Count - 1); 吧? 因为如果我们得到例如索引5,而列表中只有5个元素,我认为会导致超出范围异常。 但我喜欢你的解决方案。 - Hazaaa

3
试试这样做。
int start2 = caminohormiga[ran.Next(0, caminohormiga.Length)];

代替
int start2 = random.Next(0, caminohormiga.Length);

0
Console.Write(caminohormiga[start2]);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接