我只是注意到這是LINQtoSQL,而不是LINQtoObjects。使用Marc的代碼獲取數(shù)據(jù)庫(kù)來(lái)為您完成此操作。我把這個(gè)答案放在這里,作為L(zhǎng)INQtoObjects的潛在興趣點(diǎn)。
奇怪的是,你其實(shí)不需要拿到伯爵。但是,除非得到計(jì)數(shù),否則需要獲取每個(gè)元素。
您可以做的是保留“當(dāng)前”值和當(dāng)前計(jì)數(shù)的概念。獲取下一個(gè)值時(shí),取一個(gè)隨機(jī)數(shù),并將“Current”替換為“new”,概率為1/n,其中n是計(jì)數(shù)。
所以當(dāng)您讀取第一個(gè)值時(shí),總使之成為“當(dāng)前”值。當(dāng)您讀取第二個(gè)值時(shí),強(qiáng)權(quán)使其為當(dāng)前值(概率為1/2)。當(dāng)您讀取第三個(gè)值時(shí),強(qiáng)權(quán)使當(dāng)前值(概率為1/3)等等,當(dāng)您用完數(shù)據(jù)時(shí),當(dāng)前值是您所讀取的所有值中的隨機(jī)值,且概率是一致的。
若要將其應(yīng)用于條件,只需忽略任何不符合條件的內(nèi)容。最簡(jiǎn)單的方法是首先應(yīng)用WHERE子句,只考慮開頭的“匹配”序列。
下面是一個(gè)快速實(shí)現(xiàn)。我想沒(méi)事的.。
public static T RandomElement<T>(this IEnumerable<T> source,
Random rng){
T current = default(T);
int count = 0;
foreach (T element in source)
{
count++;
if (rng.Next(count) == 0)
{
current = element;
}
}
if (count == 0)
{
throw new InvalidOperationException("Sequence was empty");
}
return current;}