【问题标题】:Intersection of lists列表的交集
【发布时间】:2011-11-18 15:41:32
【问题描述】:

有没有更好、更优雅、更简洁的方法来获取 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

这种笨拙的根本原因是 IEnumerable 与具体容器和数组之间的不对称性。

我一直惊讶于 C# 标准库设计得多么糟糕,因为这类问题一直在出现。

有没有更好的,这意味着更优雅和简洁的方式来做到这一点?

【问题讨论】:

  • 您不知道如何正确使用它们的事实并不意味着标准库设计不佳......恕我直言,相反,它们设计得非常好(嗯,大多数其中是)。 BTW,dtb 提出的方案和你的 Ruby 方案几乎一模一样。
  • 花10分钟学习LINQ的基础知识,你会很快发现.Net集合库非常丰富。当我用其他语言编写代码时,我经常发现自己在编写 LINQ 方法。
  • 有什么理由不广泛使用 LINQ?在什么情况下会出现这种情况?
  • 我看不出任何理由,除了必须维护旧的 .net3.5 之前的代码。在某些情况下,使用 linq 的解决方案很难像使用经典结构的解决方案那样高效,但我发现这些解决方案非常罕见。所以,只要从你能得到的地方取最好的,它可能会将你的名字改为“istilldontlikemsbutsometimesitisnottoobadactually”;)。

标签: c# ruby list intersection


【解决方案1】:

您可以使用Enumerable.IntersectEnumerable.ToList extension methods 如下获得非常优雅简洁的代码:

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

【讨论】:

  • 我知道这一点,但它需要使用 System.Linq;
  • System.Linq 是 .Net 框架的一部分,从 3.5 版本开始
  • 排除 linq 的意思是,“除了更好的方法之外,为什么没有更好的方法来做到这一点?”
【解决方案2】:
    // 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);
        }
    }

【讨论】:

    猜你喜欢
    • 2018-04-24
    • 2013-07-03
    • 1970-01-01
    • 2011-10-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-25
    • 2011-04-20
    • 2016-03-23
    相关资源
    最近更新 更多