Есть два основных подхода, которые можно использовать, когда вы хотите получить «N случайных предметы из коллекции ".
- Выберите случайный элемент, убедитесь, что он не был выбран раньше, если он был, выберите новый.
- Смешайте всю коллекцию, затем возьмите первые N предметов.
Вы выбираете второй вариант (хотя вы использовали неэффективный и предвзятый способ сделать это).
Что лучше, ну, это зависит. Во-первых, технически первый вариант - O (бесконечность), потому что существует возможность случайного выбора одного и того же элемента снова и снова. Если вы хотите говорить о средних случаях, это станет правильным вариантом для рассмотрения.
Первый вариант лучше всего, когда количество элементов, которые вы хотите, представляет собой небольшой процент от общего размера коллекции. Если вы хотите захватить только 1% предметов коллекции, то шансы случайного выбора уже выбранных предметов очень и очень малы.
Второй вариант, перетасовка, с другой стороны, лучше, если вы хотите, чтобы процентные элементы в коллекции составляли , потому что вы выполняете ту же работу независимо от того, хотите ли вы 1 элемент или все их. Если вы хотите только 1% предметов в коллекции, вы в конечном итоге тратите массу усилий на перетасовку данных, которые вам просто не нравятся.
Теперь, что мы должны были действительно хотите сделать случайным образом перетасовать первые N элементов коллекции, но без перетасовки всех предметов, которые остались.
Интересно, что на самом деле это очень легко сделать. Гораздо более предпочтительный метод перетасовки списка - это отсчет с самого высокого индекса до самого низкого, выберите элемент под текущим индексом и замените его текущим индексом. Это не приводит к смещению, в отличие от сортировки, это O (n) в отличие от сортировки, которая является O (n * log (n)), и, что еще лучше, это супер легко остановить путь части.Так что, если мы реализуем этот перетасовки алгоритм:
public static IEnumerable<T> Shuffle<T>(
this IEnumerable<T> source, Random random)
{
var list = source.ToList();
for (int i = list.Count; i > 0; i--)
{
var index = random.Next(i);
var temp = list[index];
list[index] = list[i - 1];
list[i - 1] = temp;
yield return temp;
}
}
Теперь мы можем выписать свое решение, как:
var selectedHorses = unasignedHorses.Shuffle(rand).Take(numberHorses);
это, кажется, достаточно хорошо. он возвращает случайный список лошадей? – BlaShadow
«или еще лучший способ» ... похоже, вы просите мнение? Я не уверен, что сообщество будет очень восприимчиво к этому, но я могу ошибаться. Существует много разных способов сделать это. Если это сработает и имеет смысл для вас, сохраните его как есть. – Jfabs
Является ли список лошадей, поступающих из базы данных? – DavidG