2017-08-06 20 views
1

我想編寫一個函數序列,當給定一個字符串將其傳遞給所有創建的函數並生成一個修改過的字符串。 例如生成和組合來自集合的函數

string[] arr = {"po", "ro", "mo", "do"}; 

var modify = "pomodoroX"; 
foreach (var token in arr) 
{ 
    modify = modify.Replace(token, ""); 
} 
Console.WriteLine(modify); // Output: X 

這解決了問題,但我感興趣的是功能性的解決方案:

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. 

所以基本上,採取陣「改編」,併爲每個字符串創建一個函數,刪除該字符串。 目前的解決方案是有缺陷的,只適用於最後一個功能,我似乎無法將其轉換爲代表,以他們+=運營商結合起來。

還是有更好的功能解決方案?

回答

3

那麼,你的Select賦予您參加一個字符串,併產生修改後的字符串代表的集合,所以你已經完成一半了。所有你需要的是把這些在一起,通過Aggregate鏈 - 和你做的是如下的方式:

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". 
+0

非常感謝朋友! Soo函數的組成與數學fn(fn2(param))一樣。 – rinormaloku

+0

@rinormaloku,這是完全正確的。 –

1

我真的不知道「功能」纔算數。我假設你不想使用任何流量控制結構。

這是簡單的,你不覺得嗎?

string[] arr = {"po", "ro", "mo", "do"}; 
arr.Aggregate("pomodoroX", (x, y) => x.Replace(y, "")) 
+0

酷,剛開始學習C#的,它是如此的強大。 (我仍然在想Java的方式)。 隨着功能我的意思是不是有一個變量,我不斷地修改外部。這樣我們通過一系列函數傳遞它們,每個函數都進行修改並將其作爲參數傳遞給另一個函數。 – rinormaloku