РЕДАКТИРОВАТЬ: я обнаружил две превосходные имплементации после небольшого копания, поэтому я бы предложил те, которые предпочтительнее.
Метод расширения для этой цели и уже был предложен ранее здесь Я включил код, перефразированный в Shuffle ниже.
public static IEnumerable<T> Shuffle<T> (this IEnumerable<T> source)
{
Random random = new Random ();
T [] copy = source.ToArray ();
for (int i = copy.Length - 1; i >= 0; i--)
{
int index = random.Next (i + 1);
yield return copy [index];
copy [index] = copy [i];
}
}
И интересное решение, адаптированное из этого подхода linq
public static IEnumerable<T> Shuffle<T> (this IEnumerable<T> source)
{
Random random = new Random ();
return source.OrderBy(i => Random.Next()).AsEnumerable();
}
Оригинальный ответ, но медленнее, чем правки
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> sequence)
{
Random random = new Random();
List<T> copy = sequence.ToList();
while (copy.Count > 0)
{
int index = random.Next(copy.Count);
yield return copy[index];
copy.RemoveAt(index);
}
}
Если вам нравится один из них, вам следует проголосовать за связанный ответ.
Если вы очень обеспокоены случайностьюВы можете перейти на один из алгоритмов RNG из Crypto API и заполнить его каким-нибудь недетерминированным значением, например, чем-то, сгенерированным в результате недавней активности мыши.Я подозреваю, что это было бы излишним, и это ухудшило бы производительность.