2013-03-13 54 views
2

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

回答

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); 
0

我会做这样的:

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

由于乔恩所指出的,最好的方法是使用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)));