How to replace LINQ nested loops in a clean, manageable way

Codewise, what is the cleanest way to do this using linq? Below is an example where I want to find the appropriate instance of a class based on the name.

class item { string name {get;set;} int identifier {get;set;} } void DoSomething() { List<item> List1 = GetSampleItems(); List<item> List2 = GetOtherSampleItems(); for(int a=0;a<List1.count;a++) { for(int b=0;b<List2.count;b++) { if(List1[a].identifier == List2[b].identifier) { List1[a].name = List2[b].name; } } } } 
+6
source share
3 answers

Linq is for queries, not updates, so you'll need to look at the results to make changes, but you can join combine these two lists:

 var query = from l1 in List1 join l2 in List2 on l1.identifier equals l2.identifier select new {l1, l2}; 

Now run a query loop to update l1 elements:

 foreach(var item in query) item.l1.name = item.l2.name; 

As a side note, there is nothing wrong with how you do this (except you could break out of the inner loop if a match is found). If you understand how this works and the performance is acceptable, there is no good reason to change it.

+10
source

This should work:

 var query = from l1 in List1 join l2 in List2 on l1.identifier equals l2.identifier select new { l1values = l1, l2Name = l2.name }; foreach(var item in query) item.l1Values.name = item.l2Name; 
+4
source

Better use Dictionary<TK,TV> :

 Dictionary<int,item> l2dic = List2.ToDictionary(x => x.identifier); item itm; List1.ForEach(x => { if(l2dic.TryGetValue(x.identifier,out itm)) { x.name = itm.name; } }); 

Or, as @Rawling says, use the foreach instead:

 Dictionary<int,item> l2dic = List2.ToDictionary(x => x.identifier); item itm; foreach(item x in List1) { if(l2dic.TryGetValue(x.identifier,out itm)) { x.name = itm.name; } } 

An ideal demonstration (with minor changes to the item class).

This runs on average linear time, while your approach works in quadratic time.

Supposed that the identifiers are unique: none of the two elements in the same list can have the same identifier.

The final note is that variables generally begin with a lowercase list1 , so list1 and list2 , while classes and properties begin with capital (these are item , Identifier and Name ).

+4
source

Source: https://habr.com/ru/post/981614/


All Articles