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?
Optimally, you want to only ever make the function query for a single value, so you set up the Skip/Take to jump up to the sequence number matching the random number you're generating (bounded by dataset's itemcount, so the missing row problem bounding based on MAX(pkey) isn't an issue) and then snag the first item at that point in the sequence.
In SQL this is the same as querying for
SELECT Count(*) FROM q
, thenSELECT * FROM q LIMIT {0}, 1
where{0}
isrand.Next(0, count)
, which should be pretty efficient.Another wacky approach (not the most efficient for larger data sets):
What about:
Further reading:
The comments below make good contributions to closely related questions, and I'll include them here, since as @Rouby points out, people searching for an answer to these may find this answer and it won't be correct in those cases.
Random Element Across Entire Input
To make all elements a candidate in the random selection, you need to change the input to
r.Next
:@Zidad adds a helpful extension method to get random element over all elements in the sequence:
I have product table in database ,every time user enters one product detail I want to show 10 similar products in below of page.And in every refresh this list must be change .it must come randomly.
Linq looks like this
this only for not put selected product to list .
It works perfect
Use a Fisher-Yates-Durstenfeld shuffle.
(You could use a helper/extension method to shuffle your
IEnumerable<T>
sequence. Alternatively, if you were using anIList<T>
you could perform an in-place shuffle, if you prefer.)I'm posting an answer because I don't have enough reputation to comment.
I like this answer:
But ElementAt is zero based, surely starting at 1 and going to Answers.Count() you are going to end up potentially throwing an out of range, and you are never going to get the first entity.
Wouldn't
Be better?