2009-03-30 11 views
6

Jestem obecnie robi jakieś problemy Projekt Eulera i wcześniejsze często obejmować takie rzeczy jak liczb Fibonacciego lub liczb pierwszych. Iterowanie nad nimi wydaje się być naturalną sprawą LINQ, przynajmniej w czytelności i dostrzeganej "elegancji" kodu (staram się używać funkcji specyficznych dla języka tam, gdzie to możliwe i stosowanych, aby poczuć język).LINQ kwerendy na możliwie nieskończony list

Mój problem jest teraz, jeśli trzeba tylko zestaw liczb aż do pewnej granicy, jak mam wyrazić to najlepiej? Obecnie mam zakodowany odpowiedni limit w iteratorze, ale bardzo chciałbym, aby moduł wyliczający zwrócił listę, dopóki coś na zewnątrz nie zdecyduje się już na kwerendę, ponieważ przekracza pewien limit. Więc zasadniczo mam potencjalnie nieskończony iterator, ale biorę tylko skończony zestaw liczb. Wiem, że takie rzeczy są trywialne w językach funkcjonalnych, ale zastanawiam się, czy C# też na to pozwala. Jedynym innym pomysłem, jaki miałem, byłoby posiadanie iteratora Primes (long), który zwraca liczby pierwsze do pewnej granicy, podobnie do innych sekwencji.

Wszelkie pomysły?

Odpowiedz

10

Większość metod LINQ (Enumerable klasy) są leniwi. Tak na przykład, nie ma nic złego:

var squares = Enumerable.Range(0, Int32.MaxValue).Select(x=>x*x); 

Można użyć metody podjąć, aby ograniczyć wyniki:

var 10squares = squares.Take(10); 

var smallSquares = squares.TakeWhile(x => x < 10000); 

EDIT: rzeczy potrzebne do uniknięcia są funkcjami, które zwracają „leniwie "ale musieć skonsumować cały wyliczony, by dać wynik. Na przykład, grupowania lub sortowania:

var oddsAndEvens = Enumerable.Range(0, Int32.MaxValue) 
          .GroupBy(x => x % 2 == 0); 
foreach (var item in oddsAndEvens) { 
    Console.WriteLine(item.Key); 
} 

(To pewnie daje OutOfMemoryExeption w 32-bitowych).

+0

Ah, ok, nie wiem TakeWhile tak daleko. Po prostu pomyślałem, że użycie Gdzie wybrać numery, które chcę, nie zadziała, ponieważ LINQ nie ma pojęcia, że ​​liczby rosną, na przykład. Brzmi nieźle, naprawdę :) – Joey

+0

+1, ładne podsumowanie. Próbowałem również trochę omówić ten temat: http://blog.casualdev.net/2009/10/linq-and-infinite-enumerations.html –