List<>中的C#对象频率,按对象属性

时间:2014-11-24 08:32:42

标签: c# .net asp.net-mvc

我有一个对象Loan,它包含一个名为Book的属性对象。

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我希望找到哪个图书在该列表中出现最多(这是最常见的一个?)。

我怎么能这样做?

2 个答案:

答案 0 :(得分:2)

您可以覆盖Equals + GetHashCode或实现自定义IEqualityComparer<Book>,您可以在许多LINQ entension方法中使用它,例如GroupBy或(我更喜欢){{ 1}}:

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

答案 1 :(得分:1)

使用GroupBy执行此操作。

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

确保书上有正常工作。它们应该按实例进行比较或覆盖等于。

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