C#将两个属性合并到一个列表中并过滤唯一值

时间:2017-01-30 15:28:15

标签: c# algorithm linq data-structures

为了解释我的问题,我使用BookBundle创建了这个简化示例,其中包含两个Book s:

public class BookBundle
{
    public Book Book1 { get; }
    public Book Book2 { get; }
}

但现在我有很多BookBundle,但我不知道我的库中有哪些独特的Book。为此,我创建了一个函数:

public static Book[] GetUniqueBooks(BookBundle[] bundles)
{
    // Return all unique books
}

实现此功能的最有效方法是什么?是否可以使用一些Linq功能,或者我应该使用ListDictionary来跟踪我在循环中找到的哪些独特项目?哪个会是最快的(最低算法复杂度)?

2 个答案:

答案 0 :(得分:5)

您可以使用SelectMany中的System.Linq

bundles.SelectMany(b => new Book[] {b.Book1, b.Book2}).Distinct();

答案 1 :(得分:3)

一个简单的实现,可以解决您的问题,并且如果您创建同一本书的两个不同实例,也可以使用。

public Book[] GetUniqueBooks(BookBundle[] bundles)
{
    Dictionary<string, Book> dict = new Dictionary<string, Book>();
    foreach (BookBundle b in bundles)
    {
        Book bk;
        if(!dict.TryGetValue(b.Book1.ISBN, out bk))
            dict.Add(b.Book1.ISBN, b.Book1);
        if (!dict.TryGetValue(b.Book2.ISBN, out bk))
            dict.Add(b.Book2.ISBN, b.Book2);

    }
    return dict.Values.ToArray();
}

当然,这假设您已在班级中定义了唯一标识该书的属性。在这种情况下,我使用国际标准书号作为词典中的关键