How to make these foreach loops efficient?

I have a list (PatchFacilityManager) and a list of objects (Int) of a ManagerId object. I want to make the code below effective. Is there a way to remove these two foreach loops.

foreach (PatchFacilityManager PM in patchFacilityManager) { foreach (int FM in facilityManagerId) { if (PM.FacilityManagerId == FM) { PM.IsSelected = true; } } } 
+4
source share
7 answers

Here is one way

  foreach (PatchFacilityManager PM in patchFacilityManager) { PM.IsSelected = facilityManagerId.Contains(PM.FacilityManagerId); } 

EDIT

This solution is effective in two in three IMHO ways compared to the code given in the question.

First , it does not check the condition, and the result of the expression is immediately assigned to PM.IsSelected. According to LukeH's comment , it is not necessary to set PM.IsSelected to false, so the condition is inevitable. However, this improvement is applicable if the given should set to false. Hit>. From the answer to the question about the author, his case seems to be going right with this optimization. So there is no need for a conditional appointment.

Second , it does not iterate over the entire list, as List.Contains (int) returns true and exits the loop in the first occurrence of the int passed in the argument.

Third , when the environment provides you with List.Contains (int) functionality, then why reinvent the wheel. Thus, in terms of service, it is also more efficient.

+7
source
 patchFacilityManager .Where(c => facilityManagerId.Contains(c.FacilityManagerId)) .ForEach(c => c.IsSelected = true); 
+1
source
 var ids = new HashSet<int>(facilityManagerId); foreach (PatchFacilityManager pfm in patchFacilityManager) { if (ids.Contains(pfm.FacilityManagerId)) pfm.IsSelected = true; } 
+1
source

You can store the object manager identifier in an array in sorted order, and then view them using BinarySearch instead of foreach .

0
source
 patchFacilityManager .Where(m => facilityManagerId.Contains(m.FacilityManagerId)) .ToList() .ForEach(m => m.IsSelected = true); 

or

 patchFacilityManager .Join(facilityManagerId, m => m.FacilityManagerId, f => f, (m,f) => m) .ToList() .ForEach(m => m.IsSelected = true); 
0
source

Another option using LINQ syntax:

 var match = for PM in patchFacilityManager join FM in facilityManager on PM.FacilityManagerId equals FM select PM; foreach(var PM in match) { PM.IsSelected = true; } 
0
source

Just for fun and out of the box - an approach where lists are sorted:

 static void Main(string[] args) { List<int> nums = new List<int>(new int[] { 1, 2, 3, 4, 5, 6, 7, 8 }); List<int> ids = new List<int>(new int[] { 2, 4, 5 }); for (int i = 0, j = 0; i < nums.Count && j < ids.Count; i++) { int num = nums[i]; int id = ids[j]; if (num == id) { Console.WriteLine("Match = " + id); j++; } } Console.ReadLine(); } 

I do not think that I did not know about work efficiency or about canceling this idea. Of course, you can change this to use the main foreach for numbers, and you manually use the ID Enumerator inside the main foreach if you are allergic to fors.

0
source

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


All Articles