2011-11-18 50 views
4

是否有更好,更優雅和簡潔的方式來獲取C#中的兩個列表的交集?列表的交集

在C#中的方法來計算的日期列表的交集是:

public List<DateTime> dates_common(Timeserie ts1, Timeserie ts2) 
    { 
     var dt1 = new HashSet<DateTime>(ts1.dates); 
     var dt2 = new HashSet<DateTime>(ts2.dates); 
     dt1.IntersectWith(dt2); 
     var dt = new DateTime[dt1.Count]; 
     dt1.CopyTo(dt); 
     return new List<DateTime>(dt); 
    } 

在Ruby一個會做如:

def dates_common(ts1, ts2) 
    dt1 = ts1.dates.to_set  
    dt2 = ts2.dates.to_set 
    return dt1.intersection(dt2).to_a 
end 

此clunkiness的根本原因是之間的不對稱IEnumerable和具體的容器和數組。

隨着這種問題一直出現,我總是驚訝於C#標準庫的設計有多糟糕。

有沒有更好的,這意味着更優雅和簡潔的方式來做到這一點?

+5

,你不知道如何使用它們的事實正確並不意味着標準庫的設計很糟糕...恕我直言,他們是,相反,非常好設計(好吧,其中大部分是)。順便提一下,dtb提出的解決方案几乎與您的Ruby解決方案完全相同。 –

+2

花10分鐘時間學習LINQ的基礎知識,你會很快發現.Net集合庫非常豐富。當我用其他語言編寫代碼時,我經常發現自己正在編寫LINQ方法。 –

+0

有沒有任何理由不廣泛使用LINQ?情況如何? – ihatems

回答

16

您可以使用Enumerable.Intersect和​​extension methods如下得到非常優雅,簡潔的代碼:

public List<DateTime> dates_common(Timeserie ts1, Timeserie ts2) 
{ 
    return ts1.dates.Intersect(ts2.dates).ToList(); 
} 
+0

我意識到這一點,但它需要使用System.Linq; – ihatems

+0

System.Linq是.Net框架的一部分,從3.5版本 – WarHog

+8

開始,不包括linq在說:「爲什麼沒有更好的方法來做到這一點,而不是更好的方式來做到這一點? – 2011-11-18 17:10:58

0
// This function is used to remove those alias from 'cc' which are common in 'to' and 'cc' list. 

    private static void RemoveCommonFromCc(ref List<string> to, ref List<string> cc) 
    { 
     IEnumerable<string> common = (List<string>)to.Intersect(cc); 
     foreach(var removeCc in common) 
     { 
      cc.Remove(removeCc); 
     } 
    }