如何使用linq将代理聚合到新的委托中

时间:2013-03-13 21:58:17

标签: c# linq functional-programming aggregate

假设我有IEnumerable<Func<object, bool>>。我想创建一个新的Func<object, bool>,如果该列表的每个函数在某个对象上调用时返回true,则返回true。换句话说,我想聚合(reduce \ foldl)一个函数列表。

3 个答案:

答案 0 :(得分:5)

这样做:

Func<object, bool> aggregate = o => functions.All(f => f(o));

当然这是作弊,因为函数碰巧返回bool,所以我们可以直接使用Enumerable.All来产生聚合结果。这也有副作用,即不会调用列表中的所有函数 - 只要一个人返回false,我们就会打包并离开。

在一般情况下,这种处理是使用Enumerable.Aggregate完成的,可以这样:

Func<object, bool> aggregate = o => 
    functions.Select(f => f(o))
             .Aggregate(true, (result, @partial) => result && @partial);

答案 1 :(得分:1)

Jon指出,最好的方法是使用Enumerable.All。但是,您可以使用Aggregate折叠序列,这样您也可以这样做:

Func<object, bool> folded = funcs.Aggregate((acc, f) => new Func<object, bool>(o => acc(o) && f(o)));

此重载要求序列非空,但您可以为累加器提供初始值:

Func<object, bool> folded = funcs.Aggregate(new Func<object, bool>(_ => true), (acc, f) => (o => acc(o) && f(o)));

答案 2 :(得分:0)

我会这样做:

bool evaluateAllFuncs(object someObject)
{
    IEnumerable<Func<object, bool>> funcs = GetAllFuncs();
    return funcs.All(f => f(someObject)));
}