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;
精彩评论