我有以下课程:
public class Question
{
public int QuestionId { get; set; }
public string Title { get; set; }
}
在一个变量中我有:
IEnumerable<Question> _questions = GetQuestions.Get();
如何获取变量 _questions 中的问题集合并从集合中随机返回 1 到 4 个随机问题的列表?
我有以下课程:
public class Question
{
public int QuestionId { get; set; }
public string Title { get; set; }
}
在一个变量中我有:
IEnumerable<Question> _questions = GetQuestions.Get();
如何获取变量 _questions 中的问题集合并从集合中随机返回 1 到 4 个随机问题的列表?
您可以先随机播放列表,然后使用Take()
var result = _questions.OrderBy(x => Guid.NewGuid())
.Take(new Random().Next(4) + 1);
您可以使用Reservoir Sampling单次遍历未知大小的序列,以随机选择 N 个项目集:
public static List<T> RandomlyChooseItems<T>(IEnumerable<T> items, int n, Random rng)
{
var result = new List<T>(n);
int index = 0;
foreach (var item in items)
{
if (index < n)
{
result.Add(item);
}
else
{
int r = rng.Next(0, index + 1);
if (r < n)
result[r] = item;
}
++index;
}
return result;
}
你像这样使用它:
IEnumerable<Question> questions = ...;
Random rng = new Random();
int questionCount = rng.Next(1, 5); // Get between 1 and 4 questions.
List<Question> randomQuestions = RandomlyChooseItems(questions, questionCount, rng);
这通常不会比将项目复制到数组中并执行 a 更有效率Fisher-Yates shuffle
,但如果要选择的列表的大小非常大并且要选择的项目数量相对较少,则可能很有用,因为您只需要存储所选项目而不是原始项目列表。