hong pei
hong pei

Reputation: 929

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

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
}

Upvotes: 5

Views: 1596

Answers (3)

Eric Lippert
Eric Lippert

Reputation: 660004

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?

Upvotes: 6

Nasmi Sabeer
Nasmi Sabeer

Reputation: 1380

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
        }

Upvotes: 3

Zbigniew
Zbigniew

Reputation: 27584

var result = items.Where(i => Predicate(i, obj));

Upvotes: 8

Related Questions