Извлечение ключевого слова Linq - ограничение объема извлечения - PullRequest
3 голосов
/ 07 ноября 2010

Относительно это решение .

Есть ли способ ограничить количество ключевых слов, которые необходимо учитывать? Например, я бы хотел, чтобы вычислялись только первые 1000 слов текста. В Linq есть метод «Take», но он служит другой цели - все слова будут вычислены, и будет возвращено N записей. Как правильно сделать это правильно?

Ответы [ 3 ]

2 голосов
/ 07 ноября 2010

Просто примените Take раньше - сразу после звонка на Split:

var results = src.Split()
                 .Take(1000)
                 .GroupBy(...) // etc
1 голос
/ 07 ноября 2010

Ну, строго говоря, LINQ не обязательно собирается читать все; Возьми остановится как можно скорее. Проблема в том, что в связанном вопросе вы смотрите на Count, и трудно получить Count без использования всех данных. Аналогично, string.Split будет смотреть на все .

Но если вы написали ленивую небуферизующую функцию Split (с использованием yield return) и хотели получить первые 1000 уникальных слов, то

var words = LazySplit(text).Distinct().Take(1000);

будет работать

1 голос
/ 07 ноября 2010

Enumerable.Take действительно поток результатов;он не буферизирует свой источник целиком, а затем возвращает только первое N. Хотя, глядя на ваше исходное решение, проблема в том, что ввод, где вы хотите сделать Take, равен String.Split.К сожалению, этот метод не использует какого-либо отложенного выполнения;он охотно создает массив всех «разбиений» и затем возвращает его.

Следовательно, методика получения потоковой последовательности слов из некоторого текста будет выглядеть примерно так:

var words = src.StreamingSplit()  // you'll have to implement that            
               .Take(1000);

Однако я отмечу, что остальная часть вашего запроса:

...
.GroupBy(str => str)   // group words by the value
.Select(g => new
             {
                str = g.Key,      // the value
                count = g.Count() // the count of that value
              });

Обратите внимание, что GroupBy - это операция буферизации - вы можете ожидать, что все 1000 слов из ее источника будут храниться где-то в процессе передачи групп.

Как я понимаю, варианты:

  1. Если вы не возражаете, просматривая весь текст для разбиения целей, тогда src.Split().Take(1000) подойдет.Недостатком является потраченное впустую время (чтобы продолжить расщепление после того, как оно больше не нужно) и пустое пространство (для хранения всех слов в массиве, даже если только первая тысяча) потребуется.Однако rest запроса не будет обрабатывать больше слов, чем необходимо.
  2. Если вы не можете позволить себе сделать (1) из-за нехватки времени / памяти, используйте src.StreamingSplit().Take(1000) или эквивалентный.В этом случае исходный текст не будет обработан после того, как будет найдено 1000 слов.

Обратите внимание, что эти 1000 слов сами в конечном итоге будут буферизованы предложением GroupBy в обоих случаях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...