开发者

Any suggest to store a value in a lambda expression

I'm trying to write an in-line function for count occurrences of a word in a string using lambda expressions recursively.

The function开发者_StackOverflow:

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;

The problem is that I'm call IndexOf method twice, The first one is for recursive break condition and the second one is to get the value for add it.

Is there any suggest to call it once?

Thanks in advance.


If you don't mind a non-pure-function lambda you can do:-

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;
}


You could do it like this:

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; 


I suggest you make it a separate method

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

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

or inline

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

with lambda syntax but just another way of writing the above

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


You could use an additional, anonymous lambda and invoke it immediately. I'm not certain of the exact C# syntax, but it should look something like:

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))


My usual solution to these kind of problems, ignoring any optimizations, is just to remove the matching term and check any change in the resulting string's length.

Func<String, String, Int32> getOccurrences = (text, term) => 
    (text.Length - text.Replace(term, "").Length) / term.Length;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜