Reputation: 135
How might I take two random records from a list using Linq?
Upvotes: 4
Views: 1640
Reputation: 2738
This is what ended up working for me, it ensures no duplicates are returned:
public List<T> GetRandomItems(List<T> items, int count = 3)
{
var length = items.Count();
var list = new List<T>();
var rnd = new Random();
var seed = 0;
while (list.Count() < count)
{
seed = rnd.Next(0, length);
if(!list.Contains(items[seed]))
list.Add(items[seed]);
}
return list;
}
Upvotes: 0
Reputation: 1473
For Linq-to-Objects
and EF4
it's pretty simple
db.Users.OrderBy(r => Guid.NewGuid()).Take(2)
For Linq-to-SQL
You can check this article
http://michaelmerrell.com/2010/03/randomize-result-orders-in-t-sql-and-linq-to-sql/
Add function Random mapped to SQL function NEWID
to DataContext.
partial class DataContext
{
[Function(Name = "NEWID", IsComposable = true)]
public Guid Random()
{
throw new NotImplementedException();
}
}
Usage
var qry = from row in DataBase.Customers
where row.IsActive
select row;
int count = qry.Count();
int index = new Random().Next(count);
Customer cust = qry.Skip(index).FirstOrDefault();
Upvotes: 3
Reputation: 7334
Why do you want to use Linq to get two random records?
Create a Random instance and get two random number whose values are less than the length of the list.
List has Indexer property, so doing List[index] is not costly.
Keep it simple. Always prefer readability. If you just make things complicated, the programmers who are going to maintain your code will have hard time.
I am just curious to know why exactly you want to do this in Linq? That just seems like a overhead to me.
am I missing something?
Upvotes: -1
Reputation: 12776
Random rnd = new Random();
var sequence = Enumerable.Range(1, 2).Select(n => lst[rnd.Next(0, lst.Count)]).ToList();
Upvotes: 3
Reputation: 22587
There is no direct way. You can try this, not pretty though.
int randomRecord = new Random().Next() % List.Count(); //To make sure its valid index in list
var qData = List.Skip(randomRecord).Take(1);
var qValue = qData.ToList().First();
Upvotes: 2