【问题标题】:C# Intersect beetween multiple objects listsC# 多个对象列表之间的交集
【发布时间】:2023-03-27 09:05:01
【问题描述】:

我有下一个情况:

public class ParentClass
{
    public string Name { get; set; }

    public List<ChildClass> ChildrenList {get;set;}
}

public class ChildClass
{
    public string Name { get; set; }

    public GrandChildClass GrandChild { get; set; }
}

public class GrandChildClass
{
    public string Name { get; set; }
}

GrandChildClass grandChild1 = new GrandChildClass() { Name = "AAA1" };
GrandChildClass grandChild2 = new GrandChildClass() { Name = "BBB1" };
GrandChildClass grandChild3 = new GrandChildClass() { Name = "CCC1" };
GrandChildClass grandChild4 = new GrandChildClass() { Name = "DDD1" };

ChildClass child1 = new ChildClass() { Name = "AAA", GrandChild = grandChild1 };
ChildClass child2 = new ChildClass() { Name = "BBB", GrandChild = grandChild2 };
ChildClass child3 = new ChildClass() { Name = "CCC", GrandChild = grandChild3 };
ChildClass child4 = new ChildClass() { Name = "DDD", GrandChild = grandChild4 };
ChildClass child5 = new ChildClass() { Name = "EEE", GrandChild = grandChild2 };

List<ParentClass> parentsList = new List<ParentClass>()
{
    new ParentClass { Name = "Parent1", ChildrenList = new List<ChildClass>() { child1, child2 } },
    new ParentClass { Name = "Parent2", ChildrenList = new List<ChildClass>() { child3, child4 } },
    new ParentClass { Name = "Parent3", ChildrenList = new List<ChildClass>() { child1, child5 } }
}

我想用最简单的方法找出哪些父母有共同的孩子。

我不想做一些 foreach 循环并进行比较,但我想使用 linq 函数,例如 Intersect 或类似的函数。

例如,这里有一个类似的东西,它正在工作:

List<List<string>> lists = new List<List<string>>()
{
    new List<string> {"Hello", "World", "7"},
    new List<string> {"Hello", "7", "Person"},
    new List<string> {"7", "7", "Hello"}
};

List<string> extList = lists.Cast<IEnumerable<string>>()
                .Aggregate((a, b) => a.Intersect(b)).ToList();

就我而言,我希望结果是: Parent1 和 Parent3 有共同的 child1。

有什么想法吗?

编辑:

另外,如何找到所有有共同孙子的父母?

【问题讨论】:

  • 澄清一下:如果孩子共享Name而不是同一个对象实例,则认为它是平等的?
  • 同一个对象实例。

标签: c# list intersection


【解决方案1】:

您可以按孩子分组,然后选择有多个父母的组:

var result = parentsList.SelectMany(p => p.ChildrenList.Select(c => (child: c, parent: p)))
    .GroupBy(c => c.child, c => c.parent)
    .Where(g => g.Count() > 1);

我已修改您的输入并将Name 属性添加到父类:

List<ParentClass> parentsList = new List<ParentClass>()
{
    new ParentClass { Name = "p1", ChildrenList = new List<ChildClass>() { child1, child2 } },
    new ParentClass { Name = "p2", ChildrenList = new List<ChildClass>() { child3, child4 } },
    new ParentClass { Name = "p3", ChildrenList = new List<ChildClass>() { child1, child5 } }
};

下一个代码

foreach (var child in result)
    Console.WriteLine(String.Join(", ", child.Select(p => p.Name)));

将打印

p1, p3

【讨论】:

    【解决方案2】:

    您正在寻找类似的东西:

    var results = parentsList
      .SelectMany(parent => parent.ChildrenList)
      .Distinct()
      .Select(child => new 
              { 
                  Child = child, 
                  Parents = parentsList.Where(parent => parent.ChildrenList.Contains(child)) 
              });
    

    您需要将 ChildrenLists 展平并区分它们。接下来,您应该选择孩子以及在 ChildrenList 中拥有该孩子的所有父母。

    我已经命名了父母以获得更有用的结果:

    AAA => X, Z
    BBB => X
    CCC => Y
    DDD => Y
    EEE => Z
    

    就我而言,它说,这个孩子有这些父母。

    【讨论】:

      【解决方案3】:

      您可以使用下一个代码找到所有具有相同引用的孩子:

      List<ChildClass> result = parentsList.SelectMany(x => x.ChildrenList)
      .GroupBy(x => x).Where( x=> x.Count() > 1)
      .SelectMany(x => x).Distinct().ToList() ;
      

      顺便说一句,由于在每个子列表中遇到“Hello”,您的代码正在工作,在第二个列表中跳过它,结果列表将为空:

      List extList = lists.Cast>() .Aggregate((a, b) => a.Intersect(b)).ToList();

      【讨论】:

        【解决方案4】:

        为我使用的父母寻找共同的孩子:

        var results = parentsList
            .SelectMany(p => p.ChildrenList)
            .Distinct()
            .Select(child => new
            {
                Child = child,
                Parents = parentsList.Where(p => p.ChildrenList.Contains(child)).ToList()
            }).ToList();
        

        为我使用的父母寻找共同的孙子:

        var results = parentsList
            .SelectMany(p => p.ChildrenList)
            .Distinct()
            .Select(child => new
            {
                child.GrandChild,
                Parent = parentsList.Where(p => p.ChildrenList.Any(c => c.GrandChild == child.GrandChild)).ToList()
            }).GroupBy(c => c.GrandChild)
            .Select(group => group.First());
        

        感谢 Jeroen van Langen 的回答。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-03-18
          • 2019-07-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-15
          • 1970-01-01
          相关资源
          最近更新 更多