I want to compose a sequence of functions that when given a string passes it through all the created functions and produces a modified string. e.g.
string[] arr = {"po", "ro", "mo", "do"};
var modify = "pomodoroX";
foreach (var token in arr)
{
modify = modify.Replace(token, "");
}
Console.WriteLine(modify); // Output: X
This solves the problem, but I am interested in the Functional solution:
Console.WriteLine(
arr.Select<string, Func<string, string>>(val => (s1 => s1.Replace(val, string.Empty)))
.Aggregate((fn1, fn2) => fn1 += fn2)
.Invoke("pomodoroX")
);
// Output: pomoroX -> Only last element applied because:
// the functions are not getting combined.
So basically, take the array "arr" and for each string create a function that removes that string.
The current solution is flawed and applies only the last function and I can't seem to convert this to delegates so as to combine them with +=
operator.
Or are there better functional solutions?
Well, your Select
gives you the collection of delegates which take in a string, and produce the modified string, so you're halfway there. All you need is to chain these together via Aggregate
- and the way you do it is as follows:
string[] arr = { "po", "ro", "mo", "do" };
string result = arr
// Produce our collection of delegates which take in the string,
// apply the appropriate modification and return the result.
.Select<string, Func<string, string>>(val => s1 => s1.Replace(val, string.Empty))
// Chain the delegates together so that the first one is invoked
// on the input, and each subsequent one - on the result of
// the invocation of the previous delegate in the chain.
// fn1 and fn2 are both Func<string, string>.
.Aggregate((fn1, fn2) => s => fn2(fn1(s)))
.Invoke("pomodoroX");
Console.WriteLine(result); // Prints "X".