Reputation: 3761
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();
Upvotes: 3
Views: 123
Reputation: 1053
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();
Upvotes: 1
Reputation: 31596
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
What did the lookup look like? For it did the heavy lifting for us.
Upvotes: 2
Reputation: 1245
You can also extract the location ids into a separate list, and use that in the Where()
clause, together with an xor for the IsNone
. Combining that with the Except()
operator solution of @leigh-shepperson, you get this:
var locationIds = locationsToCompare.Select(location => location.ID);
noneEmployees = employees.Where(employee => !company.IsNone ^ locationIds.Contains(employee.LocationID));
locationEmployees = employees.Except(noneEmployees);
I don't know if that's the most readable solution, but it makes it possible to make it shorter.
Upvotes: 1