List<int> source = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Random r = new Random();
for (int i = 0; i < 100; i++)
{
Console.WriteLine($"Random: {source.RandomElement(r)}");
}
![](https://img2018.cnblogs.com/blog/1865358/201912/1865358-20191202164011975-827211799.png)
/// <summary>
/// 从序列中选择随机元素
/// O(n)序列中每个元素被选择的机会是均等的,而且我们只迭代了一次
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="random">同一个Random</param>
/// <returns></returns>
public static T RandomElement<T>(this IEnumerable<T> source, Random random)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (random == null)
{
throw new ArgumentNullException("random");
}
ICollection collection = source as ICollection;
if (collection != null)
{
int count = collection.Count;
if (count == 0)
{
throw new InvalidOperationException("Sequence was empty.");
}
int indx = random.Next(count);
return source.ElementAt(indx);
}
using (IEnumerator<T> iter = source.GetEnumerator())
{
if (!iter.MoveNext())
{
throw new InvalidOperationException("Sequence was empty.");
}
int cntSoFar = 1;
T current = iter.Current;
while (iter.MoveNext())
{
cntSoFar++;
if (random.Next(cntSoFar) == 0)
{
current = iter.Current;
}
}
return current;
}
}