Linq to compare two collections in C #

I want to compare the two collections in C # that I am currently doing using a nested for loop. is there a way in linq to do the same thing that will be faster and more efficient? here is my current code that works great looking for an efficient way:

OrgCollection myYears = Org.RetrieveDistinctYear(); if (myYears.Count > 0) { AcademicYearCollection allYears = AcademicYear.RetrieveAll(); for (int i = 0; i < myYears.Count; i++) { for (int j = 0; j < allYears.Count; j++) { if (myYears[i].AcademicYearCode == allYears[j].Code) { ddlYear.Items.Insert(0, new ListItem(allYears[j].Name,allYears[j].Code)); break; } } } } 

I want to compare the "Code" with the AcademicYearCollection with the "AcademicYearCode" property in the OrgCollection, and if it is the same, add it to the "ddlYear" drop-down list.

Thanks in advance.

+4
source share
4 answers

You can do this in LINQ, which gives a shorter code. To find out whether it is more effective or not, you will need to profile it. I think the linq join operator actually uses some kind of hash bucket that should provide better performance, especially if the collections are large. Your current solution is O (N ^ 2), which will quickly deteriorate if the number of options increases.

 OrgCollection myYears = Org.RetrieveDistinctYear(); AcademicYearCollection allYears = AcademicYear.RetrieveAll(); var items = from y in myYears join ay in allYears on y.Code equals ay.AcademicYearCode select new { ay.Name, ay.Code } 
+14
source
 OrgCollection myYears = Org.RetrieveDistinctYear(); if (myYears.Count > 0) { AcademicYearCollection allYears = AcademicYear.RetrieveAll(); for (int i = 0; i < myYears.Count; i++) { if (allYears[j].Any(allY => allY == myYears[i].AcademicYearCode )) { ddlYear.Items.Insert(0, new ListItem(allYears[j].Name, allYears[j].Code)); break; } } } 

This may be an option, but I think the extension method "any" works the same way, iterating through.

0
source

How about this

 var allYears = AcademicYear.RetrieveAll().ToDictionary(y => y.Code, y.Name); ListItem match = null; foreach(var year in Org.RetrieveDistinctYear()) { if (allYears.HasKey(year.AcademicYearCode) { match = new ListItem( allYears[year.AcademicYearCode], year.AcademicYearCode); break; } } if (match != null) { ddlYear.Items.Insert(0, match); } 

Using Dictionary here provides superior performance, and the further the results of Org.RetrieveDistinctYear match, the greater the benefit. If the results of RetrieveDistinctYear are often short or the match is at the top, the overhead of creating a dictionary will make the code invisible.


EDIT

Or this approach

 var allYears = AcademicYear.RetrieveAll().ToDictionary(y => y.Code, y.Name); var matchingCode = Org.RetrieveDistinctYear() .Select(y = y.AcademicYearCode) .FirstOrDefault(code => allYears.HasKey(code)); if (!string.IsEmptyOrWhitespace(matchingCode)) { ddlYear.Items.Insert(0, new ListItem( allYears[matchingCode], matchingCode)); } 
0
source

This solution has similar speed and efficiency with your original solution, but you can parallelize it by changing from y in myYears to from y in myYears.AsParallel() to speed it up.

 OrgCollection myYears = Org.RetrieveDistinctYear(); AcademicYearCollection allYears = AcademicYear.RetrieveAll(); var items = from y in myYears let match = allYears.FirstOrDefault( ay => y.AcademicYearCode == ay.Code) where match != null select new ListItem(match.Name, match.Code); 
0
source

All Articles