如何使用Linq获取随机对象

Luk*_*101 28 .net c# linq random

我想在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++;
}
Run Code Online (Sandbox Code Playgroud)

这是最好的方法吗?

cod*_*zen 39

关于什么:

SelectedPost = q.ElementAt(r.Next(1, Answers.Count()));
Run Code Online (Sandbox Code Playgroud)

进一步阅读:

下面的评论对密切相关的问题做出了很好的贡献,我将它们包含在这里,因为正如@Rouby指出的那样,搜索这些答案的人可能会找到这个答案,但在这些情况下这些答案是不正确的.

整个输入的随机元素

要使所有元素成为随机选择中的候选元素,您需要将输入更改为r.Next:

SelectedPost = Answers.ElementAt(r.Next(0, Answers.Count()));
Run Code Online (Sandbox Code Playgroud)

@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)];
}
Run Code Online (Sandbox Code Playgroud)

  • 哦,我理解一些名叫Jon Skeet的人可能对C#有所了解,并写了一本关于它的书.;) (3认同)
  • 如果你想找到一个通用的解决方案,这个方法永远不会返回第一个元素:)`public static T Random <T>(这个IEnumerable <T>可枚举){var r = new Random(); var list =可枚举为IList <T> ?? enumerable.ToList(); return list.ElementAt(r.Next(0,list.Count())); }` (2认同)

Luk*_*keH 9

使用Fisher-Yates-Durstenfeld shuffle.

(你可以使用一个辅助/扩展方法来洗你的IEnumerable<T>序列.另外,如果你使用IList<T>,你可以执行就地洗牌,如果你喜欢.)


BFr*_*ree 8

另一个古怪的方法(对大型数据集来说效率最高):

SelectedPost = q.OrderBy(qu => Guid.NewGuid()).First();
Run Code Online (Sandbox Code Playgroud)