0

I have a query that returns list of results. I want a single random item from that list.

var query = (from...
            where...
            select q).Random(1); //Something like this?

How to do this? Suppose there is 1 item i want that one to be selected. If there are more then i want one of those to be selected in a random order.

nebula
  • 3,932
  • 13
  • 53
  • 82

3 Answers3

4
var query = (from...
            where...
            orderby Guid.NewGuid()
            select q).First();
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
0

You could utilise the Shuffle example posted in Randomize a List in C# in conjunction with the LINQ Take method to create an extension method on an IList<T>, you'd need to ToList your selection prior to calling Random, unless you moved that inside the extension.

public static List<T> Random<T>(this IList<T> list, int takeNumber)
{
    return list.Shuffle().Take(takeNumber);
}

public static List<T> Shuffle<T>(this IList<T> list)  
{  
    Random rng = new Random();  
    int n = list.Count;  
    while (n > 1) {  
        n--;  
        int k = rng.Next(n + 1);  
        T value = list[k];  
        list[k] = list[n];  
        list[n] = value;  
    }

    return list;
}
Community
  • 1
  • 1
Richard
  • 8,110
  • 3
  • 36
  • 59
0

This Shuffle Method is better than others answers. it will not cost any performance issue when chaining and it's still LINQ.

public static IEnumerable<T> TakeRandom<T>(this IEnumerable<T> source, int count)
{
    return source.Shuffle().Take(count);
}

public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)
{
    return source.OrderBy(x => Guid.NewGuid());
}

Usage:

var query = (from...
        where...
        select q).TakeRandom(1);
shtse8
  • 1,092
  • 12
  • 20