How to use local variables in lambda expression

I have 2 list objects 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 need to get all the identifiers from the "pr" ListObject, which has no record or an odd number of entries in the "tem" ListObejct. using llamas.

To do this, I 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 great.

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

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

More simply, I just want to use it once for two conditions here.

+7
list c # lambda linq
source share
5 answers

Use lambda instead of lambda expression

 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; } )); 
+14
source share

Maybe just:

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

returns two people:

 2 "rezoan" 5 "marman" 
+4
source share

Besides the lambda expression, you can use let clause :

 HashSet<string> inconsistantIDs = new HashSet<string>( from p in pr let count = tem.FindAll(t => t.id == p).Count where count == 0 || count % 2 != 0 select p.id ); 
+3
source share
 HashSet<string> inconsistantIDs = new HashSet<string>( pr.Select(p => new { Id = p.id, Cnt = tem.FindAll(t => t.id == p.id).Count() }) .Where(p => p.Cnt == 0 || p.Cnt % 2 != 0) .Select(p => p.Id); 
+2
source share

On the side of the note, strictly speaking, you will get better performance if you created a hash mapping of each identifier to its account, and then do a loop search.

Now you have the O(n*m) algorithm, which will be reduced to O(n+m) :

 // create a map (id -> count), O(m) operation var dictionary = new Dictionary<string, int>(); foreach (var p in tem) { var counter = 0; dictionary.TryGetValue(p.id, out counter); counter++; dictionary[p.id] = counter; } // search the map, O(n) operation var results = new HashSet<string>(); foreach (var p in pr) { var counter = 0; dictionary.TryGetValue(p.id, out counter); if (counter == 0 || counter % 2 != 0) results.Add(p.id); } 
+2
source share

All Articles