How to get a Random Object using Linq

2019-02-05 14:58发布

I am trying to get a random object within linq. Here is how I did.

//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++;
}

Is this the best way to do this?

9条回答
等我变得足够好
2楼-- · 2019-02-05 15:57

Generic extension method based on the accepted answer (which doesn't always skip the first, and only enumerates the enumerable once):

 public static class EnumerableExtensions
    {
        public static T Random<T>(this IEnumerable<T> enumerable)
        {
            var r = new Random();
            var list = enumerable as IList<T> ?? enumerable.ToList();
            return list.ElementAt(r.Next(0, list.Count()));
        }
    }
查看更多
淡お忘
3楼-- · 2019-02-05 16:01

Pulling all of the answers and looping them isn't the most efficient way as you're moving lots of data from the database. If you're using an integer primary key that's automatically incrementing, you should get the Max of your primary key and then find the random integer within that range. Then directly get the single answer based on the primary key derived from the random function.

查看更多
淡お忘
4楼-- · 2019-02-05 16:04

Late to the party but this is a high-up Google result. A succinct version could be:

var rnd = new Random();
var SelectedPost = q.OrderBy(x => rnd.Next()).Take(1);

It has the disadvantage that it'll apply a random number to all elements, but is compact and could easily be modified to take more than one random element.

查看更多
登录 后发表回答