Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combine Multiple Predicates

Is there any way in c# .NET 2.0! to combine multiple Predicates?

Let's say I have the following code.

List<string> names = new List<string>(); names.Add("Jacob"); names.Add("Emma"); names.Add("Michael"); names.Add("Isabella"); names.Add("Ethan"); names.Add("Emily");  List<string> filteredNames = names.FindAll(StartsWithE);  static bool StartsWithE(string s) {     if (s.StartsWith("E"))     {         return true;     }     else     {         return false;     } } 

This gives me:

Emma Ethan Emily 

So this is pretty cool stuff, but I know want to be able to filter using multiple predicates.

So I want to be able to say something like this:

List<string> filteredNames = names.FindAll(StartsWithE OR StartsWithI); 

In order to get:

Emma Isabella Ethan Emily 

How can I achieve this? Currently I am just filtering the complete list twice and combining the results afterwards. But unfortunately this is quite inefficent and even more importantly I lose the original sort order, which is not acceptable in my situation.

I also need to be able to iterate over any number of filters/predicates as there can be quite a lot.

Again it needs to be a .NET 2.0 solution unfortunately I can't use a newer version of the framework

Thanks a lot.

like image 639
eric Avatar asked Aug 08 '09 07:08

eric


People also ask

How do you combine two predicates?

When two sentences have the same subject, we can combine their predicates using a special word called a conjunction. Conjunctions are words like 'and', 'but', and 'so'. They combine sentences or parts of sentences. To combine predicates, we use the conjunction 'and'.

How to combine two predicates in Java?

The Predicate or() method is used to combine a Predicate instance with another, to compose a third Predicate instance. The composed Predicate will return true if either of the Predicate instances it is composed from return true , when their test() methods are called with same input parameter as the composed Predicate .

What is predicate C#?

Predicate in general meaning is a statement about something that is either true or false. In programming, predicates represent single argument functions that return a boolean value.


1 Answers

How about:

public static Predicate<T> Or<T>(params Predicate<T>[] predicates) {     return delegate (T item)     {         foreach (Predicate<T> predicate in predicates)         {             if (predicate(item))             {                 return true;             }         }         return false;     }; } 

And for completeness:

public static Predicate<T> And<T>(params Predicate<T>[] predicates) {     return delegate (T item)     {         foreach (Predicate<T> predicate in predicates)         {             if (!predicate(item))             {                 return false;             }         }         return true;     }; } 

Then call it with:

List<string> filteredNames = names.FindAll(Helpers.Or(StartsWithE, StartsWithI)); 

Another alternative would be to use multicast delegates and then split them using GetInvocationList(), then do the same thing. Then you could do:

List<string> filteredNames = names.FindAll(Helpers.Or(StartsWithE+StartsWithI)); 

I'm not a huge fan of the latter approach though - it feels like a bit of an abuse of multicasting.

like image 92
Jon Skeet Avatar answered Sep 19 '22 10:09

Jon Skeet