Question

I have this function and I want to get distinct value in # Data #. but my problem is if there are two value with the same characters but one is Upper and one is Lower (i.e Comedy and comedy) it still have both value Comedy and comedy in my Data. So when I bind to Data...it shows both.

My function is:

public void LoadBookGenre(Book abc)
{
    var loadbook = from Book s in BookDB.Books where s.Genre == abc.Genre select s;
    BookAttribute.Clear();
    foreach (Book m in loadbook) BookAttribute.Add(m);
    List<Book> distinct = BookAttribute.GroupBy(a => a.Genre).Select(g => g.First()).ToList(); 
    Data.Clear(); 
    foreach (Book s in distinct) Data.Add(s);
}
Was it helpful?

Solution

You can use the GroupBy overload that allows you to specify a case-insensitive comparer:

List<Book> distinct = 
    BookAttribute.GroupBy(a => a.Genre, StringComparer.OrdinalIgnoreCase)
                 .Select(g => g.First())
                 .ToList();

Depending on your scenario, you might also be able to use Distinct:

List<string> distinctGenres = 
    BookAttribute.Select(a => a.Genre)
                 .Distinct(StringComparer.OrdinalIgnoreCase)
                 .ToList();

Edit: You also need to alter the equality check in your initial query:

var loadbook = from Book s in BookDB.Books 
               where s.Genre.Equals(abc.Genre, StringComparison.OrdinalIgnoreCase)
               select s;

OTHER TIPS

The common solution is to maintain a version of the string that is forced to upper or lower case with upper() or lower(), and use that internal string for comparisons and the original string as the "display" version.

Replace

Data.Add(s);

by

var found = Data.SingleOrDefault(x => x.Genre.ToUpperInvariant() == s.Genre.ToUpperInvariant());
if (found == null)
{
    Data.Add(s);
}

This way, you avoid adding the same name twice, while keeping the casing of the first one you find.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top