6

我有两个通用列表,一个称为“精选”,另一个称为“过滤”。

List<Content> Featured = new List<Content>();
List<Content> Filtered = new List<Content>();

两者都包含“内容”项目,它们是简单的类,如下所示:

public class Content
{
    public long ContentID { get; set;}
    public string Title { get; set; }
    public string Url { get; set; }
    public string Image { get; set; }
    public string Teaser { get; set; }

    public Content(long contentId, string title, string url, string image, string teaser)
    {
        ContentID = contentId;
        Title = title;
        Url = url;
        Image = image;
    }
}

任何出现在“已过滤”中但也出现在“精选”中的项目都需要从“已过滤”中删除。此外,这两个列表随后将合并为一个通用列表,其中“精选”项目首先出现。

我知道我可以编写几个 foreach 循环来做到这一点,但我不禁觉得必须有一个使用 LINQ 的更优雅的方法。

我正在使用 C# 4.0。

4

3 回答 3

6

您正在寻找 LINQ 方法Union,特别是

var singleList = Featured.Union(Filtered);

这将返回所有Featured项目,然后是所有Filtered不是的项目Featured。请注意,它还将删除列表的任何重复项 - 因此,如果一个项目是Featured两次,它只会出现一次

但是,您确实需要能够比较的实例Content才能做到这一点,方法是添加 和 的实现EqualGetHashCode提供一个IEqualityComparer.

于 2012-07-09T13:11:48.530 回答
6

如果您定义了 IEqualityComparer,则可以使用以下Union方法:

List<Content> FeaturedAndFiltered = Featured.Union(Filtered, new MyContentComparer());

MyContentComparer 的粗略实现是:

public class ContentEqualityComparer : IEqualityComparer<Content>
{

    public bool Equals(Content c1, Content c2)
    {
        return (c1.ContentID == c2.ContentID);
    }


    public int GetHashCode(Content c)
    {
        return c.ContentID.GetHashCode();
    }

}
于 2012-07-09T13:08:55.347 回答
2

假设两个列表中的 objects presenter 是实际相同的对象,您可以执行以下操作:

var totalList = Featured
    .Concat(Filtered.Where(f => !Featured.Contains(f)))
    .ToList()

更新

或者,使用 Mahmoud Gamal 提到的 except 方法:

var totalList = Featured
    .Concat(Filtered.Except(Featured))
    .ToList()
于 2012-07-09T13:11:23.757 回答