2014-01-14 41 views
0

我的對象有3個字段 - Term,Subject和Marks。我想要列出任何主題的標記不同的項目。比較兩個列表以獲取LinQ中的瀑布圖數據

如:

首先列出

Term1, English,90 
Term1, Maths, 60 
Term1, Physics, 30 

第二個列表

Term2, English, 95 
Term2,Maths, 60 
Term2, Chemistry, 20 

最後我要的是

English : +5 
Physics : +30 
Chemistry : -20. 

我使用下面的查詢來獲取差異,但是如果這個失敗了, E鍵字段(在這種情況下,主題)值不在兩個列表相同(如:-Chemistry出現在列表2,但不是在列表1)

var diffData = list1.Union(list2) 
         .GroupBy(m => m.Subject) 
         .Select(d=> 
         { 
          Subject= d.Key, 
          Difference = d.OrderBy(m =>m.Term).Select(s => s.Mark).Aggregate(t1, t2) => t2 - t1) 
         }).Where(m => m.Difference != 0).ToList(); 

請幫

+0

你想化學是+20和物理是-30?看起來這樣會更符合英文+5。 –

+0

@steaks我需要一個完整的外連接。我常見的類別是,那麼我需要他們的區別 –

+0

我知道你想要一個完整的外部聯接。但是,我不明白你想如何改變。考慮到英語,物理和化學差異的跡象,沒有一致的方法來應對差異。 –

回答

0

嘗試這種方式,你簡直是你的輸出

var Outpt = (from a in List1 
      from b in List2 
      where a.Subject == b.Subject 
      Select new {subject = a.subject , marks = a.marks - b.marks , a.Term}).ToList(); 
+0

@Robert_Junior你檢查了它 –

+0

@ Co.Aden Nope。請理解這個問題。如果我應用上述查詢,我​​會錯過物理學,化學,因爲它們在列表中不常見 –

1
var diffs = list1.Union(list2) 
    //Create groups where the key is subject and the value is the 
    //list of positive marks for Term2 and negative marks for Term1 
    .GroupBy(c => c.Subject, c => c.Term == "Term2" ? c.Mark : -c.Mark) 
    .Select(s => new 
     { 
      Subject = s.Key, 
      Difference = s.Sum() 
     }) 
    .Where(s => s.Difference != 0); 

var diffs2 = list1.Union(list2) 
    .GroupBy(c => c.Subject) 
    .Select(s => 
     { 
      //For a more general and slighly different algorithm, you can 
      //subtract all the marks for a each subject except the last term 
      //mark from the last term mark (e.g. 95 - 90 for English or 30 - 
      //n/a because there's only one term for Physics 
      var marks = s.OrderByDescending(c => c.Term).Select(c => c.Mark); 
      var lastTermMark = marks.First(); 
      return new 
       { 
        Subject = s.Key, 
        Difference = marks.Skip(1) 
         .Aggregate(lastTermMark, (diff, mark) => diff - mark) 
       }; 
     }) 
    .Where(s => s.Difference != 0);