2014-11-24 81 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。

根據情況,這不是一個好的解決方案。當對象存儲在數據庫中時,可能有很多這樣的對象,您應該考慮使用數據庫查詢來查找最常用的書。