Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use local variables in a lambda expression

Tags:

c#

list

lambda

linq

I have 2 list object of type of some class,

 class person
    {
        public string id { get; set; }
        public string name { get; set; }
    }

List<person> pr = new List<person>();
pr.Add(new person { id = "2", name = "rezoan" });
pr.Add(new person { id = "5", name = "marman" });
pr.Add(new person { id = "3", name = "prithibi" });

List<person> tem = new List<person>();
tem.Add(new person { id = "1", name = "rezoan" });
tem.Add(new person { id = "2", name = "marman" });
tem.Add(new person { id = "1", name = "reja" });
tem.Add(new person { id = "3", name = "prithibi" });
tem.Add(new person { id = "3", name = "prithibi" });

Now i have to get all the ids from "pr" ListObject that has no entry or odd number of entries in the "tem" ListObejct. using lamda.

To do this i have used,

HashSet<string> inconsistantIDs = new HashSet<string>(pr.Select(p => p.id).Where(p => tem.FindAll(t => t.id == p).Count == 0 || tem.FindAll(t => t.id == p).Count % 2 != 0));

and it works fine.

but you can see from the code i have used tem.FindAll(t => t.id == p).Count twice to comapre with ==0 and %2!=0.

Is there any way to use tem.FindAll(t => t.id == p).Count once and save it to a temporary variable and then compare this variable with ==0 and %2!=0.

More simply i just want to use it once for two condition here.

like image 775
Rezoan Avatar asked Sep 06 '13 12:09

Rezoan


People also ask

How do you use local variables in lambda expression?

A lambda expression can't define any new scope as an anonymous inner class does, so we can't declare a local variable with the same which is already declared in the enclosing scope of a lambda expression. Inside lambda expression, we can't assign any value to some local variable declared outside the lambda expression.

Can you pass local variables to lambda expressions?

In this case, a lambda expression may only use local variables that are effectively final. An effectively final variable is one whose value does not change after it is first assigned. There is no need to explicitly declare such a variable as final, although doing so would not be an error.

Why do local variables used in lambdas have to be final?

The basic reason this won't compile is that the lambda is capturing the value of start, meaning making a copy of it. Forcing the variable to be final avoids giving the impression that incrementing start inside the lambda could actually modify the start method parameter.

Can we use Non final variable in lambda?

A lambda expression can use a local variable in outer scopes only if they are effectively final.


2 Answers

Use a statement lambda instead of an expression lambda

var inconsistantIDs = new HashSet<string>(
           pr.Select(p => p.id).Where(p => 
                  {
                    var count = tem.FindAll(t => t.id == p).Count;
                    return count == 0 || count % 2 != 0;
                  }
           ));
like image 73
Ahmed KRAIEM Avatar answered Sep 28 '22 07:09

Ahmed KRAIEM


Perhaps simply:

var query = pr.Where(p => { int c = tem.Count(p2 => p.id == p2.id); return c == 0 || c % 2 != 0; });

returns two persons:

2   "rezoan"
5   "marman"
like image 23
Tim Schmelter Avatar answered Sep 28 '22 07:09

Tim Schmelter