2012-11-20 108 views
1

我有2個列表,我需要鞏固。表1只的日期,並列出2可有時間元素,以及:有沒有更簡潔的方式來表達這個foreach循環?

var List1 = new[] { 
    new ListType{ val = new DateTime(2012, 1, 1)}, 
    new ListType{ val = new DateTime(2012, 1, 2)} 
}; 

List2 = new[] { new ListType{ val = new DateTime(2012, 1, 1, 5, 0, 0)} }; 

FinalList = new[] { 
    new ListType{ val = new DateTime(2012, 1, 1, 5, 0, 0)}, 
    new ListType{ val = new DateTime(2012, 1, 2)} 
}; 

我要對這個辦法是:

foreach (var l in List1) { 
    var match = List2.FirstOrDefault(q => q.val.Date == l.val); 
    if (match == null) continue; 
    l.val = match.val; 
} 

難道還有比通過迭代更好的辦法List1,使用FirstOrDefault然後重新分配val?它可以工作,所以如果Linq有一種更優雅的方式(即我缺少一些明顯的東西),這只是一種好奇心。

感謝

+1

你調查過加入功能? – Timo

+0

所以,你是從'List2'複製時間部分到'List1'的相應成員? –

+0

丹:確切無誤 – Rob

回答

0

可以使用Enumerable.Union使用自定義IEqualityComparer<ListType>

class ListType 
{ 
    public DateTime val { get; set; } 

    public class DateComparer : IEqualityComparer<ListType> 
    { 
     public bool Equals(ListType x, ListType y) 
     { 
      if (ReferenceEquals(x, y)) 
       return true; 
      else if (x == null || y == null) 
       return false; 
      return x.val.Date == y.val.Date; 
     } 

     public int GetHashCode(ListType obj) 
     { 
      return obj.val.Date.GetHashCode(); 
     } 
    } 
} 

然後......

var finalList = List2.Union(List1, new ListType.DateComparer()); 
+0

噢嘿...那/是/一個好主意..謝謝隊友。我知道SO會通過。 – Rob

+0

'finalList'最終包含'List2'中的日期值,它們不出現在'List1'中,並且也從List1中刪除重複項。 – Rawling

+0

Rawling:我可以處理細節。我在尋找IEqualityComparer。這會使我指向正確的方向。在實際的解決方案中,有比日期更多的邏輯,但是我可以將它放入DateComparer類中,然後使用它。 – Rob

0

我不會擺脫循環,但效率我會建立一個字典映射日期到第一個matchnig時間:

var dateToTime = List2 
    .GroupBy(d => d.Date) 
    .ToDictionary(g => g.Key, g => g.First()); 
foreach (var l in List1) 
{ 
    DateTime match; 
    if (dateToTime.TryGetValue(l.val, out match)) 
     l.val = match.val; 
} 

LINQ用於查詢項目而不是更新項目 - 如果您需要更新項目,請使用非LINQ類似foreach循環的內容。這就是說,如果你想生成從第一列表中的項目一名單,以下是你的代碼的等效代碼:

var newList = List1.Select(l => new ListType { val = 
    dateToTime.ContainsKey(l.val) ? dateToTime[l.val] : l.val }).ToList(); 
+0

我不反對,這就是我所需要的。我不知道它/看/爲IEqualityComparer。還有一個好處(我也沒有在問題中包含),因爲我可以在其他類中重用比較器。 – Rob

相關問題