Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to combine these two LINQ statements into one

Tags:

c#

.net

linq

I need to produce 2 separate lists out of 1 list. If company.IsNone is true, I want all employees added to the first list that match the locationsToCompare list, if its not true, I want all of the employees that don't match the locationsToCompare list. This is the exact opposite when populating the second list. Is there a way to combine these two if statements into one, or am I forced to have two separate to populate the two lists?

var noneEmployees = company.IsNone
       ? employees.Where(employee => locationsToCompare.Any(x => x.ID == employee.LocationID)).ToList()
       : employees.Where(employee => locationsToCompare.All(x => x.ID != employee.LocationID)).ToList();

var locationEmployees = company.IsNone
       ? employees.Where(employee => locationsToCompare.All(x => x.ID != employee.LocationID)).ToList()
       : employees.Where(employee => locationsToCompare.Any(x => x.ID == employee.LocationID)).ToList();
like image 645
mameesh Avatar asked Dec 03 '25 02:12

mameesh


2 Answers

The group of employees is dependent on whether a company IsNone flag is set.

But before figuring that out, let us group the employees using the ToLookup(TSource, TKey) which is a dictionary/grouping type lookup where the key is whether the employee is in the locationsToCompare list.

Once the lookup is setup, we can the pipe in the company IsNone flag and extract the employees.


Example Setup Data

var employees = new List<Employee>
         { new Employee { LocationID = 1, Name = "Hamilton" },
           new Employee { LocationID = 2, Name = "Joe"      },
           new Employee { LocationID = 1, Name = "Frank"    },
           new Employee { LocationID = 5, Name = "Reynolds" } };

var company = new Company() { IsNone = false };

Locations

var locationsToCompare = new List<Location> { new Location() { ID = 1 },
                                              new Location() { ID = 2 } };

Contains

I will eventually use a Contains in lieu of a where clause so I will distill the locationsToCompare into a list of ids.

var LocationIds = locationsToCompare.Select(ltc => ltc.ID);

This step could be skipped, but I believe it makes it easier to maintain.

ToLookUp

Now we use the ToLookup and then extract our lists based on company 'IsNone' flag:

var empLookup = employees.ToLookup(emp => LocationIds.Contains(emp.LocationID));

var noneEmployees     = empLookup[company.IsNone].ToList();
var locationEmployees = empLookup[!company.IsNone].ToList();

Result

enter image description here


What did the lookup look like? For it did the heavy lifting for us.

enter image description here

like image 123
ΩmegaMan Avatar answered Dec 05 '25 15:12

ΩmegaMan


Try something like this, using Except so you don't have to repeat all the code:

public class Company
{
    public bool IsNone { get; set; }
}

public class Employee
{
    public int LocationID { get; set; }
}

public class Location
{
   public int ID { get; set; }
}

Operation

var locationsToCompare = new List<Location> { new Location() { ID = 1 }, new Location() { ID = 2 } };

var employees = new List<Employee> { new Employee() { LocationID = 1 }, new Employee { LocationID = 2 }, new Employee { LocationID = 1}, new Employee { LocationID = 5 } };

var company = new Company();

company.IsNone = false;

var noneEmployees = company.IsNone
                  ? employees.Where(employee => locationsToCompare.Any(x => x.ID == employee.LocationID)).ToList()
                  : employees.Where(employee => locationsToCompare.All(x => x.ID != employee.LocationID)).ToList();

var locationEmployees = employees.Except(noneEmployees).ToList();
like image 26
Leigh Shepperson Avatar answered Dec 05 '25 15:12

Leigh Shepperson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!