根据T的每个实例包含</t>的另一个列表过滤List <t>

时间:2011-12-05 15:12:13

标签: linq list lambda many-to-many filtering

所以我在一个列表中有一组对象,但该列表中的每个对象都包含另一个列表。

请考虑以下事项:

class Parent
{
    public Parent(string parentName)
    {
        this.ParentName = parentName;
    }
    public string ParentName { get; set; }
    public List<Child> Children { get; set; } 
}
class Child
{
    public Child(string name)
    {
        this.ChildName = name;
    }

    public string ChildName { get; set; }
}

根据应用程序的性质,父项列表中的所有Parent对象都是唯一的。多个父母可以包含同一个孩子,我需要得到包含孩子x的父母。

因此,假设ChildName为“child1”的孩子属于ParentName为“parent1”和“parent5”的父母。如果集合中有100个父母,我想只获得ChildName为Child1的孩子

我更喜欢用lambda表达式做这个,但我不知道从哪里开始,因为我没有太多使用它们的经验。是否有可能,如果可能,那么正确的方法是什么?

3 个答案:

答案 0 :(得分:3)

如果Child类通过实现IEquatable<Child>定义了相等操作,则可以使用lambda,LINQ的Enumerable.Where方法和List.Contains轻松完成此操作。方法:

var parents = new List<Parent> { ... }; // fully populated list of parents
var child = null; // the child you are looking for goes here
var filtered = parents.Where(p => p.Children.Contains(child));

您现在可以迭代filtered并执行您的业务逻辑。

如果Child类没有显式定义的相等操作(这意味着它将使用引用相等规则而不是检查相同的ChildName),那么你需要包含“什么”通过相同的“自己检查lambda:

var filtered = parents.Where(p => p.Children.Any(c => c.ChildName == "child1"));

注意:当然还有很多其他方法可以做到,包括可能更容易阅读

parents.Where(p => p.Children.Count(c => c.ChildName == "child1") > 0);

但是,这不如Any版本有效,即使它会产生相同的结果。

在这两种情况下,lambdas都非常“读起来”他们打算做什么:

  1. 我希望那些子集合中包含此项目的父母
  2. 我希望那些至少有一个孩子的父母ChildName == "child1"

答案 1 :(得分:3)

你可以这样做:

var result = parents.Where(p => p.Children.Any(c => c.ChildName == "child1"));

答案 2 :(得分:2)

这样做

IEnumerable<Parent> parentsWithChild1 = parents.Where(p => p.Children.Any(c => c.ChildName == "child1"));