1

Found this Post and it has good solution when shuffling items in List<T>.

But in my case i have a class Person which is defined as this:

class Person
{
   public int Id { get; set; }
   public string Name { get; set; }
   public string Position { get; set; }
}

This is my implementation and usage:

List<Person> workers = new List<Person>()
{
    new Person { Id = 1, Name = "Emp 1", Position = "Cashier"},
    new Person { Id = 2, Name = "Emp 2", Position = "Sales Clerk"},
    new Person { Id = 3, Name = "Emp 3", Position = "Cashier"},
    new Person { Id = 4, Name = "Emp 4", Position = "Sales Clerk"},
    new Person { Id = 5, Name = "Emp 5", Position = "Sales Clerk"},
    new Person { Id = 6, Name = "Emp 6", Position = "Cashier"},
    new Person { Id = 7, Name = "Emp 7", Position = "Sales Clerk"}
};

Now i want to shuffle all records and get 1 Sales Clerk. Here is my code and is working:

var worker = workers.OrderBy(x => Guid.NewGuid()).Where(x => x.Position == "Sales Clerk").First();

// This can yield 1 of this random result (Emp 2, Emp 4, Emp 5 and Emp 7).
Console.WriteLine(worker.Name); 

But according to the given Post GUID is not good for randomizing record. And the worst is i cant use Shuffle() and call the Where and First() extensions to get the desired result.

How can i do that with Shuffle() extension?

Community
  • 1
  • 1
Shift 'n Tab
  • 8,808
  • 12
  • 73
  • 117

2 Answers2

3

If the question is how to get it so you can chain Shuffle() with the rest of your Linq operators, the answer is to modify the Shuffle method to return reference to the list shuffled:

public static IEnumerable<T> Shuffle<T>(this IList<T> list)
{
    RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider();
    int n = list.Count;
    while (n > 1)
    {
        byte[] box = new byte[1];
        do provider.GetBytes(box);
        while (!(box[0] < n * (Byte.MaxValue / n)));
        int k = (box[0] % n);
        n--;
        T value = list[k];
        list[k] = list[n];
        list[n] = value;
    }

    return list;
}

Your code then becomes:

var worker = workers.Shuffle().Where(x => x.Position == "Sales Clerk").First();
gnalck
  • 972
  • 6
  • 12
1
Random oRandom = new Random(); 
var worker = workers[oRandom.Next(0,workers.Count)];
Andy
  • 49,085
  • 60
  • 166
  • 233
slnit
  • 35
  • 6