Ali
Ali

Reputation: 135

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

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

Upvotes: 4

Views: 1640

Answers (5)

Canica
Canica

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

AlfeG
AlfeG

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

Sandeep
Sandeep

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

ionden
ionden

Reputation: 12776

Random rnd = new Random();
var sequence = Enumerable.Range(1, 2).Select(n => lst[rnd.Next(0, lst.Count)]).ToList();

Upvotes: 3

A G
A G

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

Related Questions