4

How might I take two random records from a list using Linq?

Michael Petrotta
  • 59,888
  • 27
  • 145
  • 179
Ali
  • 135
  • 2
  • 3
  • 12

5 Answers5

3
Random rnd = new Random();
var sequence = Enumerable.Range(1, 2).Select(n => lst[rnd.Next(0, lst.Count)]).ToList();
ionden
  • 12,536
  • 1
  • 45
  • 37
3

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();
AlfeG
  • 1,475
  • 4
  • 18
  • 33
2

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(); 
A G
  • 21,087
  • 11
  • 87
  • 112
  • wont this overflow at the end? shouldn't it be % List.Count()-1 ? – undefined Apr 09 '12 at 03:47
  • 1
    Don't think so... `m % p` will produce values from `0` to `p-1`. – James Cronen Apr 09 '12 at 03:49
  • I think, % will always give max remainder of List.Count() - 1, which would be the last element. – A G Apr 09 '12 at 03:49
  • You're taking only one and you should take two, and this increase the odds of the last item in the list. **Your answer isn't random enough.** – gdoron Apr 09 '12 at 03:49
  • I think the above logic can be enhanced to take 2 random elements easily using the ? operator. Again I am not saying I have the perfect answer. – A G Apr 09 '12 at 03:53
0

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;
}
Canica
  • 2,650
  • 3
  • 18
  • 34
-1

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?

Sandeep
  • 7,156
  • 12
  • 45
  • 57
  • because i want display 2 records on my page which will change after every postback. so i need 2 get 2 random records from list – Ali Apr 09 '12 at 04:05