2014-11-24 74 views
-3

我有一个对象包含名为Book的属性对象的贷款。列表<>中的C#对象频率,按对象属性

class Loan { 
    Book book; 
    string user; 
} 

public class Book 
{ 

    public int BookId { get; set; } 
    public int AuthId { get; set; } 
    public int BookDetailsId { get; set; } 
    public string title { get; set; } 
    public Nullable<int> BookCopies { get; set; } 

    public virtual Auhtor Auhtor { get; set; 
    public virtual BookDetail BookDetail { get; set; } 
} 

然后,我有一个List<Loan> allLoans,我想找到这本书出现在该列表最(这是最常见的一个?)。

我该怎么做?

+4

你如何比较'Book's,当他们平等的吗? – 2014-11-24 08:33:45

+0

向我们展示您的努力,并解释什么定义了一个独特的“书”。试着看看[这个问题](http://stackoverflow.com/questions/7325278/group-by-in-linq),它的答案。 – 2014-11-24 08:35:04

+0

@TimSchmelter,我加了Book类的定义。 – CrazyDog 2014-11-24 08:39:09

回答

2

您可以覆盖Equals + GetHashCode或实现自定义IEqualityComparer<Book>,你可以在很多LINQ entension方法使用像GroupBy或(我喜欢)ToLookup

public class BookComparer : IEqualityComparer<Book> 
{ 
    public bool Equals(Book x, Book y) 
    { 
     if (x == null || y == null) return true; 
     return x.BookId == y.BookId; 
    } 

    public int GetHashCode(Book obj) 
    { 
     if (obj == null) return 0; 
     return obj.BookId; 
    } 
} 

var bookComparer = new BookComparer(); 
var bookLookup = loans.ToLookup(l => l.book, bookComparer); 
var maxCount = bookLookup.Max(bg => bg.Count()); 
IEnumerable<Book> booksWhichAppearMostOften = bookLookup 
    .Where(bg => bg.Count() == maxCount) 
    .Select(bg => bg.Key) 
    .Distinct(bookComparer); 

正如你可以看到我也考虑到多本书可能已被借出相同次数的事实。您现在可以使用foreach“消费”它们或另一种方法如ToList实现收集来自查询。

如果你只是想看到所有BookID是你可以使用String.Join

var allBookIDs = String.Join(", ", booksWhichAppearMostOften.Select(b => b.BookId)); 
1

使用GroupBy来做到这一点。

var mostWantedBook = list 
    .GroupBy(x => x.book) 
    .OrderByDescending(x => x.Count()) 
    .First() 
    .book; 

请确保您的书上有正在使用的Equals。它们应该通过实例来比较或覆盖Equals。

根据情况,这不是一个好的解决方案。当对象存储在数据库中时,可能有很多这样的对象,您应该考虑使用数据库查询来查找最常用的书。

相关问题