2010年9月1日 星期三

LINQ練習題 - 兩個集合做Union並且做Group彙總

先定義一下型別
public class SomeStatistics
{
public DateTime Day { get; set; }
public int Correct { get; set; }
public int Incorrect { get; set; }
}


然後有兩個此型別的集合
List<SomeStatistics> list1 = new List<SomeStatistics>();
list1.Add(new SomeStatistics() { Day = new DateTime(2010, 8, 1), Correct = 10, Incorrect = 2 });
list1.Add(new SomeStatistics() { Day = new DateTime(2010, 8, 2), Correct = 5, Incorrect = 3 });
list1.Add(new SomeStatistics() { Day = new DateTime(2010, 8, 3), Correct = 2, Incorrect = 4 });
list1.Add(new SomeStatistics() { Day = new DateTime(2010, 8, 4), Correct = 1, Incorrect = 5 });
 
List<SomeStatistics> list2 = new List<SomeStatistics>();
list2.Add(new SomeStatistics() { Day = new DateTime(2010, 7, 28), Correct = 10, Incorrect = 2 });
list2.Add(new SomeStatistics() { Day = new DateTime(2010, 7, 29), Correct = 11, Incorrect = 3 });
list2.Add(new SomeStatistics() { Day = new DateTime(2010, 7, 30), Correct = 12, Incorrect = 4 });
list2.Add(new SomeStatistics() { Day = new DateTime(2010, 7, 31), Correct = 13, Incorrect = 5 });
list2.Add(new SomeStatistics() { Day = new DateTime(2010, 8, 4), Correct = 5, Incorrect = 10 });

兩個集合的Union是這樣

image

可以看到最後有兩筆資料的Day是相同的,需求是要將Day做Group然後Correct、Incorrect的兩項欄位要做彙總


作法一
List<SomeStatistics> list3 = new List<SomeStatistics>();
list3.AddRange(list1);
 
foreach (var item in list2)
{
if (!list3.Select(s=>s.Day).Contains(item.Day))
{
list3.Add(item);
}
else
{
var target = list3.Where(s => s.Day == item.Day).FirstOrDefault();
target.Correct += item.Correct;
target.Incorrect += item.Incorrect;
}
}

結果顯示
image



作法二
List<SomeStatistics> result = new List<SomeStatistics>();
 
foreach (var item in list1.Union(list2).GroupBy(s=>s.Day))
{
result.Add(new SomeStatistics() { 
Day = item.Key,
Correct = list1.Union(list2).Where(s => s.Day == item.Key).Select(s => s.Correct).Sum(),
Incorrect = list1.Union(list2).Where(s => s.Day == item.Key).Select(s => s.Incorrect).Sum()
});
}

結果顯示
image



第一個方法是比較制式的,而第二個作法就有用到GroupBy與Sum方法

只是個練習題,但我想應該還有更加精簡而有效率的方法吧!?

希望能有朋友可以不吝指教更好的方法

謝謝




沒有留言:

張貼留言

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。