Любые предлагают сохранить значение в лямбда-выражении - PullRequest
1 голос
/ 25 октября 2010

Я пытаюсь написать встроенную функцию для подсчета вхождений слова в строку с использованием рекурсивных лямбда-выражений.

Функция:

Func<string, string, int> getOccurrences = null;
getOccurrences = (text, searchTerm) =>
  text.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase) == -1
  ? 0
  : getOccurrences(
      text.Substring(
        text.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase)
        + searchTerm.Length),
      searchTerm) + 1;

Проблема в том, что я вызываю IndexOf метод дважды, Первый предназначен для условия рекурсивного разрыва, а второй - для получения значения для его добавления.

Есть ли предложение позвонить ему один раз?

Заранее спасибо.

Ответы [ 5 ]

6 голосов
/ 25 октября 2010

Если вы не возражаете против лямбды не-чистой функции, вы можете сделать: -

Func<string, string, int> getOccurrences = null;
getOccurrences = (text, searchTerm) => 
{
   int i = text.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase);
   return i == -1 ? 0 : getOccurrences(i + searchTerm.Length), searchTerm) + 1;
}
0 голосов
/ 25 октября 2010

Мое обычное решение подобных проблем, игнорируя любые оптимизации, состоит в том, чтобы просто удалить соответствующий термин и проверить любое изменение длины полученной строки.

Func<String, String, Int32> getOccurrences = (text, term) => 
    (text.Length - text.Replace(term, "").Length) / term.Length;
0 голосов
/ 25 октября 2010

Вы можете использовать дополнительную анонимную лямбду и немедленно вызывать ее. Я не уверен в точном синтаксисе C #, но он должен выглядеть примерно так:

Func<string, string, int> getOccurrences = null;
getOccurrences = (text, searchTerm) =>
  ((index) =>
    index == -1
    ? 0
    : getOccurrences(text.Substring(index + searchTerm.Length),
        searchTerm) + 1
  )(text.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase))
0 голосов
/ 25 октября 2010

Вы можете сделать это так:

Func<string, string, int> getOccurrences =
    (text, searchTerm) => getOccurrencesInternal(
        text,
        searchTerm,
        text.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase));
Func<string, string, int, int> getOccurrencesInternal = null;
getOccurrences = (text, searchTerm, index) => 
  index == -1 
  ? 0 
  : getOccurrencesInternal( 
      text.Substring( 
        index + searchTerm.Length), 
      searchTerm) + 1; 
0 голосов
/ 25 октября 2010

Я предлагаю вам сделать это отдельным методом

   Func<string, string, int> getOccurrences = GetOccurrences;

   private int GetOccurrences(string text, string searchTerm)
   {
        //...    
   }

или встроенный

Func<string, string, int> getOccurrences = delegate(string text, string searchTerm)
                                           {
                                               //...
                                           };

с лямбда-синтаксисом, но просто еще один способ написания вышеупомянутого

Func<string, string, int> getOccurrences = (string text, string searchTerm) =>
                                           {
                                               //...
                                           };
...