2016-04-08 19 views
1

找到這個Post並且在洗牌項目List<T>時有很好的解決方案。有沒有辦法使用Shuffle()在列表中隨機檢索SINGLE RECORD? - C#

但在我來說,我有一個類Person它被定義爲這樣的:

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

這是我的實現和使用:

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"} 
}; 

現在我想洗牌的所有記錄並獲得1名銷售員。這裏是我的代碼,並正在努力:

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); 

但根據給定的Post GUID是不好的隨機記錄。最糟糕的是我無法使用Shuffle()並致電WhereFirst()擴展名以獲得所需的結果。

我該怎麼做Shuffle()擴展名?

回答

3

如果問題是如何得到它,所以你可以鏈洗牌()與您的LINQ運算符的其餘部分,答案是修改隨機方法返回參考洗牌名單:

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; 
} 

然後,您的代碼就變成了:

var worker = workers.Shuffle().Where(x => x.Position == "Sales Clerk").First(); 
+1

'VAR工人= workers.Shuffle()Firts(X => x.Position == 「銷售員」);' –

+0

真棒!很好的答案! –

+0

@JacobSeleznev多數民衆贊成在太謝謝! –

1
Random oRandom = new Random(); 
var worker = workers[oRandom.Next(0,workers.Count)]; 
相關問題