Lambda expressions, how to search inside an object?

I start to love Lambda expressions, but I try my best to convey this wall:

public class CompanyWithEmployees { public CompanyWithEmployees() { } public Company CompanyInfo { get; set; } public List<Person> Employees { get; set; } } 

My search:

 List<CompanyWithEmployees> companiesWithEmployees = ws.GetCompaniesWithEmployees(); CompanyWithEmployees ces = companiesWithEmployees .Find(x => x.Employees .Find(y => y.PersonID == person.PersonID)); 

So, I want to get a "CompanyWithEmployees" object that has this Person (Employee) that I am looking for, but I get "Can not implicit convert" Person 'To' bool ') ", which is correct, but if I don't pass Person object, how can the first search do?

+7
c # lambda
source share
6 answers

Since you want to check for availability, perhaps try:

 ces = companiesWithEmployees .Find(x => x.Employees .Find(y => y.ParID == person.ParID) != null); 

This will check any Person with the same ParID ; if you mean the same instance of Person (link), then Contains should be enough:

 ces = companiesWithEmployees .Find(x => x.Employees.Contains(person)); 
+12
source share

Find() returns the found object. Use Any() to simply check if the expression is true for any element.

 var ces = companiesWithEmployees .Find(x => x.Employees .Any(y => y.PersonID == person.PersonID)); 
+7
source share
 ces = companiesWithEmployees .First(x => x.Employees.Any(p=>p.PersonID == person.PersonID)); 
+3
source share
 ces = companiesWithEmployees.Find( x => x.Employees.Find(...) ); 

.Find returns only one object, x.Employees.Find(..) returns Person .

.Find expects a boolean parameter (i.e. the result of conditions), so a compiler error occurs that says Cannot implicit convert 'Person' To 'bool'

.Where can return multiple objects, so it can iterate through a list .

use a combination of .Where and .Any in your case.

The following code illustrates the difference between .Where , .Find and .Any :

 public partial class Form2 : Form { public Form2() { InitializeComponent(); var companiesWithEmployees = new List<CompanyWithEmployees>() { new CompanyWithEmployees { CompanyInfo = new Company { CompanyName = "Buen" }, Employees = new List<Person>() { new Person { PersonID = 1976, PersonName = "Michael" }, new Person { PersonID = 1982, PersonName = "Mark" }, new Person { PersonID = 1985, PersonName = "Matthew" }, new Person { PersonID = 1988, PersonName = "Morris" } } }, new CompanyWithEmployees { CompanyInfo = new Company { CompanyName = "Muhlach" }, Employees = new List<Person>() { new Person { PersonID = 1969, PersonName = "Aga" }, new Person { PersonID = 1971, PersonName = "Nino" }, new Person { PersonID = 1996, PersonName = "Mark" } } }, new CompanyWithEmployees { CompanyInfo = new Company { CompanyName = "Eigenmann" }, Employees = new List<Person>() { new Person { PersonID = 1956, PersonName = "Michael" }, new Person { PersonID = 1999, PersonName = "Gabby" } } } }; // just explicitly declared the types (instead of var) so the intent is more obvious IEnumerable<CompanyWithEmployees> whereAreMichaels = companiesWithEmployees .Where(cx => cx.Employees.Any(px => px.PersonName == "Michael")); string michaelsCompanies = string.Join(", ", whereAreMichaels .Select(cx => cx.CompanyInfo.CompanyName).ToArray()); MessageBox.Show("Company(s) with employee Michael : " + michaelsCompanies); Person findAga = companiesWithEmployees .Find(company => company.CompanyInfo.CompanyName == "Muhlach") .Employees.Find(person => person.PersonName == "Aga"); if (findAga != null) MessageBox.Show("Aga ID : " + findAga.PersonID.ToString()); } } class CompanyWithEmployees { public Company CompanyInfo { get; set; } public List<Person> Employees { get; set; } } class Company { public string CompanyName { get; set; } } class Person { public int PersonID { get; set; } public string PersonName { get; set; } } 
+2
source share

This is because you did not specify a legitimate Find expression for your top level Find.

I will show it here:

 ces = companiesWithEmployees .Find (x => x.Employees.Find(y => y.ParID == Person.ParID) /*condition is missing here*/); 

So, what is the condition for your initial find?

0
source share

The simplest of them is

 ces = companiesWithEmployees.FirstOrDefault(x => x.Employees.Any(y => y.PersonID == person.ParID)); 

no null check

0
source share

All Articles