我有2个列表。
var adultList = new List<Dude>();
adultList.Add(new Dude() { ID = 2, Name = "Randy Marsh" });
adultList.Add(new Dude() { ID = 3, Name = "Jimbo Kern" }); // no kids
adultList.Add(new Dude() { ID = 4, Name = "Gerald Broflovski" });
adultList.Add(new Dude() { ID = 5, Name = "Stuart McCormick" });
adultList.Add(new Dude() { ID = 6, Name = "Liane Cartman" });
adultList.Add(new Dude() { ID = 7, Name = "Ned Gerblansky" }); // no kids
var childList = new List<Dude>();
childList.Add(new Dude() { ID = 8, Name = "Stan Marsh", ParentID = 2 });
childList.Add(new Dude() { ID = 9, Name = "Kyle Broflovski", ParentID = 4 });
childList.Add(new Dude() { ID = 10, Name = "Ike Broflovski", ParentID = 4 });
childList.Add(new Dude() { ID = 11, Name = "Kenny McCormick", ParentID = 5 });
childList.Add(new Dude() { ID = 12, Name = "Eric Cartman", ParentID = 6 });
我想要一个Linq查询返回,返回没有任何孩子的adultList中的任何Dudes。结果列表也应该没有空条目(在上面的示例中,Count()应该为2,并且只返回Jimbo和Ned。)
var nullList = new List<Dude>();
nullList.Add(null);
var adultsWithNoChildren = adultList.GroupJoin(
childList,
p => p.ID,
c => c.ParentID,
(p, c) =>
{
if (c.FirstOrDefault() == null) return p;
return null;
})
.Except(nullList);
这是实现这一目标的最佳方法吗?是否有另一个Linq功能或其他? 我不喜欢创建nullList的想法,但这是唯一确保结果列表具有准确计数的。
由于
答案 0 :(得分:5)
我的方法是这样的:
var adultNoChildren = (from adult in adultList
where !childList.Any(child => child.ParentID == adult.ID)
select adult).ToList();
这也可以使用其他LINQ语法完成,但我永远不会记得:)(关于.Any的好处是它会在找到结果后立即停止,因此整个子列表只会被遍历没有孩子的成年人)
答案 1 :(得分:2)
如果列表有任何大小,我必须推荐一个涉及GroupJoin的解决方案,因为hashjoin花费n + m,而不是!任何成本核算n * m
IEnumerable<Dude> noKids =
from adult in adultList
join child in childList
on adult.ID equals child.ParentID into kids
where !kids.Any()
select adult;
或以方法形式
IEnumerable<Dude> noKids = adultList.GroupJoin(
childList,
adult => adult.ID,
child => child.ParentID,
(adult, kids) => new {Dude = adult, AnyKids = kids.Any() })
.Where(x => !x.AnyKids)
.Select(x => x.Dude);
最后,Liane真的是个老兄吗?
答案 2 :(得分:1)
adultList.Where(x => !childList.Select(y => y.ParentID).Contains(x.ID));
答案 3 :(得分:1)
var noKids = from adult in adultList
join child in childList
on adult.ID equals child.ParentID into g
from item in g.DefaultIfEmpty()
where item == null
select adult;
答案 4 :(得分:1)
var noKids = adultList.Where(a => !childList.Any(c => c.ParentID == a.ID));