2011-11-18 78 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); 
     } 
    }