2009-03-30 4 views
6

В настоящее время я выполняю некоторые проблемы с Project Euler, а ранние часто включают такие вещи, как числа Фибоначчи или простые числа. Итерация по ним кажется естественным подходом для LINQ, по крайней мере, в читабельности и воспринимаемой «элегантности» кода (я стараюсь использовать языковые функции, где это возможно и применимо, чтобы почувствовать языки).Запросы LINQ по возможно бесконечным спискам

Моя проблема сейчас, если мне нужен только набор чисел до определенного предела, как мне лучше всего это выразить? В настоящее время я жестко закодировал соответствующий предел в итераторе, но мне бы очень хотелось, чтобы перечислитель возвращал список, пока что-то снаружи не решит больше не запрашивать его, так как оно превышает определенный предел. Таким образом, в основном, у меня есть потенциально бесконечный итератор, но я беру только конечный набор чисел из него. Я знаю, что такие вещи тривиальны в функциональных языках, но мне интересно, позволяет ли это C# C#. Единственная другая идея, которая у меня была, заключалась бы в том, чтобы иметь итератор Primes (long), который возвращает числа до определенного предела, аналогично другим.

Любые идеи?

ответ

10

Большинство методов LINQ (Перечислимый класс) являются ленивыми. Так, например, нет ничего плохого:

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

Вы можете использовать метод Take, чтобы ограничить результаты:

var 10squares = squares.Take(10); 

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

Edit: вещи, которые необходимо избегать являются функции, которые возвращают «лениво «но должны потреблять все перечислимое для получения результата. Например, группировка или сортировка:

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

(Это, вероятно, даст вам OutOfMemoryExeption на 32-бит.)

+0

Ах, хорошо, не знаю TakeWhile до сих пор. Я просто подумал, что использование Where для выбора чисел, которые я хочу, не будет работать, поскольку LINQ не знает, что числа увеличиваются, например. Это звучит хорошо, действительно :) – Joey

+0

+1, приятное резюме. Я также попытался немного разъяснить эту тему: http://blog.casualdev.net/2009/10/linq-and-infinite-enumerations.html –