2009-11-27 4 views
2

어떻게 내 linq 쿼리에서 선택에서 임의의 행을 얻을 수 있습니까? 임의의 Linq 쿼리

내가 시도 :

Bot bot = (from a in dc.Bot 
      select a).OrderBy(x => Guid.NewGuid()).First(); 

그러나 작동하지 않는, 내가 같은 얻을.

답변

4

뭔가를 사용합니다 :

var random = new Random(); 
var allBots = (from a in dc.Bot select a); 

var randomAmountToSkip = random.NextInt(allBots.Count()); 
var anyBot = allBots.Skip(randomAmountToSkip).First() 
+0

Bob이 이전에 제공 한 것과 같은 답변이 아닙니까? –

+0

나는 이것이 서쪽 문제에서 금식 한 총이라고 생각한다. http://meta.stackexchange.com/questions/9731/fastest-gun-in-the-west-problem – Bob

8

나는 작동 할 수 같은 Skip

var query = from a in dc.Bot 
      select a; 

int random = new Random().Next(query.Count); 

Bot bot = query.Skip(random).First(); 
+0

+1. 현명한 소리. – RichardOD

+0

+1 - 아주 좋은 생각입니다. Guffa와 같은 확장 기능과이 기능을 결합하면 모든 세계에서 최고입니다. –

+0

@Shaul :이 방법은 쿼리를 두 번 사용하기 때문에 확장을 벗어나는 데는 적합하지 않습니다. – Guffa

2

을 내가 그 in my archive에 대한 확장 방법이 있습니다

static class IEnumerableExtensions { 

    public static T PickRandomOne<T>(this IEnumerable<T> list, Random rnd) { 
     T picked = default(T); 
     int cnt = 0; 
     foreach (T item in list) { 
     if (rnd.Next(++cnt) == 0) { 
      picked = item; 
     } 
     } 
     return picked; 
    } 

}  

사용법 :

이 방법의 장점은 미리 항목이 몇 개인 지 알 필요가 없으므로 쿼리를 두 번 실행할 필요가 없다는 것입니다.

+0

+1 - 좋은 확장! –

+0

잠깐만 - pls는 이것을 설명합니다 : foreach 루프는 "picked"값을 어떻게 설정 하겠는가? 그리고이 방법은 본질적으로 열거의 끝 부분에 항목을 선호하지 않으므로 덜 무작위로 만듭니다. –

+0

@Shaul :'rnd.Next (1)'은 항상 0을 반환하므로 첫 번째 항목은 항상 'picked'변수에 넣어집니다. 두 번째 항목은 첫 번째 항목을 50 % 확률로 대체하고 나머지는 모음 전체에서 하락 확률을 가지므로 알고리즘에 왜곡이 없습니다. – Guffa