2010-06-03 90 views
1

我有2個列表。更好的Linq查詢過濾沒有孩子的父列表

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功能還是其他的? 我不喜歡創建空列表的想法,但這是唯一的確保結果列表有一個準確的計數。

感謝

回答

5

我的做法是這樣的:

var adultNoChildren = (from adult in adultList 
        where !childList.Any(child => child.ParentID == adult.ID) 
        select adult).ToList(); 

這也可以使用其他的LINQ語法做,但我永遠記得:)(約的好處。只要它找到結果就會停下來,所以整個兒童列表僅針對沒有孩子的成年人穿過)

+0

感謝所有的答覆(安東尼,傑克,盧克)。這是最好的(減去ToList),因爲使用了Any,這對性能可能更好。 – Andre 2010-06-04 00:03:06

1
adultList.Where(x => !childList.Select(y => y.ParentID).Contains(x.ID)); 
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; 
1
var noKids = adultList.Where(a => !childList.Any(c => c.ParentID == a.ID)); 
+0

本質上只是Michael Stum從查詢理解語法到流利的擴展方法語法的答案的翻譯。 – LukeH 2010-06-04 00:03:54

2

如果列表中有任何大小的一切,我都建議涉及羣組加入一個解決方案,由於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); 

最後,是藤本真一紈絝子弟?