给出 Func<string, string>
的列表,是否可以编写一个迭代列表并返回结果的语句,如下所示:
string result = f1(f2(f..(input));
我有以下代码(有效),但我对临时变量不满意。
public static string WrapEachElementWith<T>
( this IEnumerable<T> target,
params Func<string, string>[] func )
{
string result = string.Empty;
target.Each(s =>
{
var tmp = s.ToString();
func.Reverse().Each(x => tmp = x(tmp));
result += tmp;
});
return result;
}
如何简化/重构?
更新: 我应该提供更多背景。在看到高阶 JavaScript session 和 John 在 Oredev 的滥用 c# session 后,我正在尝试使用 C# 进行函数式编程。
目的是生成html。
var TABLE = WrapWith("TABLE");
var TR = WrapWith("TR");
var TD = WrapWith("TD");
const string expected = "<TABLE><TR><TD>1</TD></TR><TR><TD>2</TD></TR></TABLE>";
var result = TABLE(stringArray.WrapEachWith(TR, TD));
result.ShouldEqual(expected);
static Func<String, String> WrapWith(string element)
{
var startTag = '<' + element + '>';
var endTag = "</" + element + '>';
return s => startTag + s + endTag;
}
最佳答案
在我看来,您正在做四件事:
- 将每个项目转换为字符串
- 依次应用函数
- 将该复合函数应用于序列中的每个字符串
- 将结果连接在一起(效率低下)
我会将这四个方面分开 - 特别是 string.Join
对于第四部分来说效果很好,并且 Enumerable.Select
第三个。
我还会避免颠倒操作顺序 - 我个人希望我指定的第一个操作是第一个应用的操作。
所以,我会重写这个方法来返回 Func<string, string>
然后可以与 Select
一起使用和Join
。例如:
public static Func<string, string> Compose(params Func<string, string> funcs)
{
return input => {
string current = input;
foreach (var func in funcs)
{
current = func(current);
}
return current;
};
}
当然,您可以自己制作这个泛型,并带有以下签名:
public static Func<T, T> Compose(params Func<T, T> funcs)
然后您可以使用以下内容来调用它:
var composite = Compose<string>(FirstFunction, SecondFunction, ThirdFunction);
var query = string.Join("", items.Select(x => x.ToString())
.Select(composite));
关于c# - 递归执行列表中的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4179492/