2013-03-13 49 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)));