C# Lambda 表达式,如何在对象内部进行搜索?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/415866/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Lambda expressions, how to search inside an object?
提问by balexandre
I'm starting to love Lambda expressions but I'm struggling to pass this wall:
我开始喜欢 Lambda 表达式,但我正在努力通过这堵墙:
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 the Object "CompanyWithEmployees" that have that Person (Employee) that I'm looking for, but I'm getting "Cannot implicit convert 'Person' To 'bool')" which is correct, but if I'm not passing the Person object, how can the first Find executes?
所以,我想得到具有我正在寻找的那个人(雇员)的对象“CompanyWithEmployees”,但我得到“无法隐式转换‘人’到‘布尔’)”这是正确的,但如果我'没有传递 Person 对象,第一个 Find 怎么能执行?
采纳答案by Marc Gravell
Because you want to check for existance, perhaps try:
因为您想检查是否存在,请尝试:
ces = companiesWithEmployees
.Find(x => x.Employees
.Find(y => y.ParID == person.ParID) != null);
This will check for any Person
with the same ParID
; if you mean the same Person
instance (reference), then Contains
should suffice:
这将检查任何Person
具有相同的ParID
; 如果您的意思是相同的Person
实例(参考),那么Contains
应该足够了:
ces = companiesWithEmployees
.Find(x => x.Employees.Contains(person));
回答by Mehrdad Afshari
ces = companiesWithEmployees
.First(x => x.Employees.Any(p=>p.PersonID == person.PersonID));
回答by Jon Limjap
That's because you haven't specified a legitimate Find expression for your top level Find.
那是因为您没有为顶级 Find 指定合法的 Find 表达式。
I'll 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?
那么你最初发现的条件是什么?
回答by David Schmitt
Find()
returns the found object. Use Any()
to just check whether the expression is true for any element.
Find()
返回找到的对象。使用Any()
刚刚检查表达式是否为任何元素如此。
var ces = companiesWithEmployees
.Find(x => x.Employees
.Any(y => y.PersonID == person.PersonID));
回答by Michael Buen
ces = companiesWithEmployees.Find( x => x.Employees.Find(...) );
.Find
returns only oneobject, x.Employees.Find(..)
returns Person
.
.Find
只返回一个对象,x.Employees.Find(..)
返回Person
.
.Find
expects boolean parameter(i.e. the result of conditions), that's why there's a compiler error that says Cannot implicit convert 'Person' To 'bool'
.Find
期望布尔参数(即条件的结果),这就是为什么有一个编译器错误说 Cannot implicit convert 'Person' To 'bool'
.Where
can return multiple objects, hence can iterate through alllist.
.Where
可以返回多个对象,因此可以遍历所有列表。
use a combination of .Where
and .Any
in your case.
使用的组合.Where
和.Any
你的情况。
the following code will illustrate the difference between .Where
, .Find
, and .Any
:
下面的代码将说明的差之间.Where
,.Find
和.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's 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; }
}
回答by Dincer Uyav
The easiest one would be
最简单的一个是
ces = companiesWithEmployees.FirstOrDefault(x =>
x.Employees.Any(y => y.PersonID == person.ParID));
without any null check
没有任何空检查