在C#中递归迭代列表

时间:2016-04-08 08:20:17

标签: c# list recursion

我正在努力学习函数式编程基础知识, 如何使用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) })

1 个答案:

答案 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的替代方案。