Я пытаюсь получить случайный объект в linq. Вот то, как я сделал.
//get all the answers
var Answers = q.Skip(1).Take(int.MaxValue);
//get the random number by the number of answers
int intRandomAnswer = r.Next(1, Answers.Count());
int count = 0;
//locate the answer
foreach(var Answer in Answers)
{
if (count == intRandomAnswer)
{
SelectedPost = Answer;
break;
}
count++;
}
Действительно ли это - лучший способ сделать это?
Как насчет:
SelectedPost = q.ElementAt(r.Next(1, Answers.Count()));
Дополнительная литература:
Комментарии, приведенные ниже, вносят хороший вклад в решение тесно связанных вопросов, и я включу их сюда, поскольку, как указывает @Rouby, люди, ищущие ответы на эти вопросы, могут найти этот ответ, и в таких случаях он не будет правильным.
Случайный элемент во всем вводе
Чтобы сделать все элементы кандидатами в случайный выбор, вам нужно изменить ввод на r.Next
:
SelectedPost = Answers.ElementAt(r.Next(0, Answers.Count()));
@Zidad добавляет полезный метод расширения к получить случайный элемент по всем элементам в последовательности:
public static T Random<T>(this IEnumerable<T> enumerable)
{
if (enumerable == null)
{
throw new ArgumentNullException(nameof(enumerable));
}
// note: creating a Random instance each call may not be correct for you,
// consider a thread-safe static instance
var r = new Random();
var list = enumerable as IList<T> ?? enumerable.ToList();
return list.Count == 0 ? default(T) : list[r.Next(0, list.Count)];
}
Используйте тасование Фишера-Йетса-Дюрстенфельда .
(Вы можете использовать вспомогательный метод / метод расширения, чтобы перетасовать вашу IEnumerable
последовательность . В качестве альтернативы, если вы использовали IList
вы можете выполнить перемешивание на месте , если хотите.)
Еще один странный подход (не самый эффективный для больших наборов данных):
SelectedPost = q.OrderBy(qu => Guid.NewGuid()).First();
Получение всех ответов и их зацикливание - не самый эффективный способ, поскольку вы перемещаете большое количество данных из базы данных. Если вы используете целочисленный первичный ключ, который автоматически увеличивается, вы должны получить максимальное значение вашего первичного ключа, а затем найти случайное целое число в этом диапазоне. Затем напрямую получите единственный ответ на основе первичного ключа, полученного из случайной функции.