Lambda表达式,如何在对象内部进行搜索?

发布于 2024-07-10 20:09:42 字数 644 浏览 7 评论 0原文

我开始喜欢 Lambda 表达式,但我正在努力越过这堵墙:

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

我的搜索:

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

所以,我想获取对象“CompanyWithEmployees”,其中包含我正在寻找的人员(员工),但我得到“无法将 'Person' 隐式转换为 'bool')”,这是正确的,但如果我不传递 Person 对象,第一个 Find 如何执行?

I'm starting to love Lambda expressions but I'm struggling to pass 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 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

花伊自在美 2024-07-17 20:09:42

因为您想检查是否存在,也许可以尝试:

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

这将检查具有相同 ParID 的任何 Person; 如果您指的是同一个 Person 实例(参考),那么 Contains 就足够了:

ces = companiesWithEmployees
        .Find(x => x.Employees.Contains(person));

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:

ces = companiesWithEmployees
        .Find(x => x.Employees.Contains(person));
冰魂雪魄 2024-07-17 20:09:42

Find() 返回找到的对象。 使用 Any() 仅检查表达式对于任何元素是否为 true。

var ces = companiesWithEmployees
    .Find(x => x.Employees
    .Any(y => y.PersonID == person.PersonID));

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

var ces = companiesWithEmployees
    .Find(x => x.Employees
    .Any(y => y.PersonID == person.PersonID));
迷鸟归林 2024-07-17 20:09:42
ces = companiesWithEmployees
    .First(x => x.Employees.Any(p=>p.PersonID == person.PersonID));
ces = companiesWithEmployees
    .First(x => x.Employees.Any(p=>p.PersonID == person.PersonID));
眼角的笑意。 2024-07-17 20:09:42
ces = companiesWithEmployees.Find( x => x.Employees.Find(...) );

.Find 返回仅一个对象,x.Employees.Find(..) 返回Person< /代码>。

.Find 需要布尔参数(即条件的结果),这就是为什么会出现编译器错误,提示 Cannotimplicit conversion 'Person' To 'bool'

.Where 可以返回多个对象,因此可以迭代所有列表。

根据您的情况使用 .Where.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; }
}
ces = companiesWithEmployees.Find( x => x.Employees.Find(...) );

.Find returns only one object, x.Employees.Find(..) returns 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'

.Where can return multiple objects, hence can iterate through all list.

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

the following code will illustrate 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'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; }
}
病女 2024-07-17 20:09:42

这是因为您没有为顶级查找指定合法的查找表达式。

我在这里展示一下:

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

那么你最初发现的条件是什么?

That's because you haven't specified a legitimate Find expression for your top level 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?

寂寞美少年 2024-07-17 20:09:42

最简单的一种是

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

没有任何空检查

The easiest one would be

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

without any null check

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文