我正在努力学习函数式编程基础知识, 如何使用C#实现相同的结果,我知道linq为这种目的提供了Select方法,但是我需要自己去理解如何对列表进行递归。(我假设Groovy重新定义了+运算符列表)。
Groovy中的/ *示例* /
def <TResult> List<TResult> Filter(List<TResult> list, Closure cls)
{
if(list.isEmpty()) {
return []
} else {
return (cls(list.head()) ? [list.head()] : []) + Filter(list.tail(),cls)
}
}
(Filter([1,2,3,4,5,6,7,8], { x-> x % 2 == 0 }))
.each( {teger -> println(teger) })
答案 0 :(得分:2)
这根本没有意义,但基本上是重新编程的C#版本的代码。就像我说的那样,在C#中没有现实世界的递归使用,但也许它可以帮助你理解语言。
public static List<TResult> Filter<TResult>(List<TResult> input, Predicate<TResult> closure)
{
if (input == null || input.Count == 0)
return new List<TResult>();
else
return (closure(input.First()) ? new List<TResult> {input.First()} : new List<TResult>())
// Replace '+'
.Union(Filter(input.Skip(1).ToList(), closure)).ToList();
}
更像c#的设计如下:
public static IEnumerable<TResult> RecursiveFilter<TResult>(IEnumerable<TResult> input, Predicate<TResult> closure)
{
// Break on end
if (input == null || !input.Any())
yield break;
// Keep going
if (closure(input.First()))
yield return current;
// Recursive progression
foreach (var filtered in RecursiveFilter(input.Skip(1), closure))
{
yield return filtered;
}
}
Yield是语法糖,它在后台创建迭代器模式。每当有人在可枚举上调用enumerator.MoveNext()
时,就会调用简单的put。有关详细信息,请查看the MSDN reference。因此,在本次考试中,它创建了一种更具功能性的递归方法,而不是简单地创建新对象。
编辑:添加了yield的替代方案。