[英]C# Intersect beetween multiple objects lists
我有下一个情况:
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。
任何的想法?
编辑:
另外,如何找到所有有共同孙子的父母?
您正在寻找类似的东西:
var results = parentsList
.SelectMany(parent => parent.ChildrenList)
.Distinct()
.Select(child => new
{
Child = child,
Parents = parentsList.Where(parent => parent.ChildrenList.Contains(child))
});
你需要压扁ChildrenLists并区分它们。 接下来,您应该选择子项以及在ChildList中拥有此子项的所有父项。
我已经为父母命名了更有用的结果:
AAA => X, Z
BBB => X
CCC => Y
DDD => Y
EEE => Z
在我的情况下它说,这个孩子有这些父母。
您可以按子组进行分组,然后选择包含多个父组的组:
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
属性添加到Parent类:
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
您可以使用下一个代码找到所有具有相同参考的孩子:
List<ChildClass> result = parentsList.SelectMany(x => x.ChildrenList)
.GroupBy(x => x).Where( x=> x.Count() > 1)
.SelectMany(x => x).Distinct().ToList() ;
BTW您的代码正在运行,因为在每个子列表中遇到“Hello”,在第二个列表中跳过它,结果List将为空:
列表extList = lists.Cast>()。Aggregate((a,b)=> a.Intersect(b))。ToList();
为了找到父母的共同孩子,我使用:
var results = parentsList
.SelectMany(p => p.ChildrenList)
.Distinct()
.Select(child => new
{
Child = child,
Parents = parentsList.Where(p => p.ChildrenList.Contains(child)).ToList()
}).ToList();
为了找到父母的共同GrandChildren,我使用:
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的答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.