Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ: is there a way to supply a predicate with more than one parameter to where clause

Tags:

c#

linq

where

wondering if there is a way to do the following: I basically want to supply a predicate to a where clause with more than one paremeters like the following:

public bool Predicate (string a, object obj)
{
  // blah blah    
}

public void Test()
{
    var obj = "Object";
    var items = new string[]{"a", "b", "c"};
    var result = items.Where(Predicate); // here I want to somehow supply obj to Predicate as the second argument
}
like image 781
hong pei Avatar asked Jan 17 '13 17:01

hong pei


People also ask

Can we use multiple where clause in LINQ?

Well, you can just put multiple "where" clauses in directly, but I don't think you want to. Multiple "where" clauses ends up with a more restrictive filter - I think you want a less restrictive one.

What is predicate in Linq C#?

A predicate, or more precisely a predicate functor, is a Boolean-valued function. It is often a unary function, checking one argument against a condition and returning the result. Disregarding functions depending on side effects, there are two nullary functions (without arguments). public static class Predicate.

What is any () in Linq?

The Any operator is used to check whether any element in the sequence or collection satisfy the given condition. If one or more element satisfies the given condition, then it will return true. If any element does not satisfy the given condition, then it will return false.

How use all in Linq C#?

The Linq All Operator in C# is used to check whether all the elements of a data source satisfy a given condition or not. If all the elements satisfy the condition, then it returns true else return false. There is no overloaded version is available for the All method.


3 Answers

var result = items.Where(i => Predicate(i, obj));
like image 90
Zbigniew Avatar answered Oct 06 '22 01:10

Zbigniew


The operation you want is called "partial evaluation"; it is logically related to "currying" a two-parameter function into two one-parameter functions.

static class Extensions
{
  static Func<A, R> PartiallyEvaluateRight<A, B, R>(this Func<A, B, R> f, B b)
  {
    return a => f(a, b);
  }
}
...
Func<int, int, bool> isGreater = (x, y) => x > y;
Func<int, bool> isGreaterThanTwo = isGreater.PartiallyEvaluateRight(2);

And now you can use isGreaterThanTwo in a where clause.

If you wanted to supply the first argument then you could easily write PartiallyEvaluateLeft.

Make sense?

The currying operation (which partially applies to the left) is usually written:

static class Extensions
{
  static Func<A, Func<B, R>> Curry<A, B, R>(this Func<A, B, R> f)
  {
    return a => b => f(a, b);
  }
}

And now you can make a factory:

Func<int, int, bool> greaterThan = (x, y) => x > y;
Func<int, Func<int, bool>> factory = greaterThan.Curry();
Func<int, bool> withTwo = factory(2); // makes y => 2 > y

Is that all clear?

like image 22
Eric Lippert Avatar answered Oct 05 '22 23:10

Eric Lippert


Do you expect something like this

        public bool Predicate (string a, object obj)
        {
          // blah blah    
        }

        public void Test()
        {
            var obj = "Object";
            var items = new string[]{"a", "b", "c"};
            var result = items.Where(x => Predicate(x, obj)); // here I want to somehow supply obj to Predicate as the second argument
        }
like image 22
Nasmi Sabeer Avatar answered Oct 06 '22 01:10

Nasmi Sabeer