-3

I have an object Loan that contains a property object called 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; }
 }

Then I have a List<Loan> allLoans and I want to find which book appears the most in that list (which is the most frequent one?).

How could I do that?

CrazyDog
  • 321
  • 3
  • 17

2 Answers2

2

You can either override Equals + GetHashCode or implement a custom IEqualityComparer<Book> which you can use in many LINQ entension methods like GroupBy or (which i prefer) 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);

As you can see i've also taken into account the fact that multiple books could have been loaned the same number of times. You can now use a foreach to "consume" them or another method like ToList to materialize a collection from the query.

If you just want to see all BookIDs you can use String.Join:

var allBookIDs = String.Join(", ", booksWhichAppearMostOften.Select(b => b.BookId));
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
1

Use GroupBy to do this.

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

Make sure you have a working Equals on the books. They should either be comparable by instance or override Equals.

Depending on the situation, this is not a good solution. When the objects are stored in a database, and there are potentially many of them, you should consider using a database query to find the most frequently used book.

Stefan Steinegger
  • 63,782
  • 15
  • 129
  • 193