tags:

views:

48

answers:

3

I have a list of customer and i need to sort and group the list according to business rule.

  • Group by Customer Name
  • Sort by Customer Name in alphabetical order
  • if there are several results for the same name, then they need to sorted by date of birth in ascending order (the oldest is listed first)

Below is the entity.

public class Customer
{
 public string FirstName {get; set;}
 public string LastName {get; set;}
 public DateTime DateofBirth {get; set;}
}

Thanks in advance.

customers.GroupBy(c => c.FirstName)
.Select(c => c.OrderBy(c => c.FirstName).ThenBy(c => c.LastName));
A: 
var sortList = (from c in customers
                             group c by new 
                             { 
                                 c.FirstName, 
                                 c.LastName, 
                                 c.DateofBirth 
                             } into g
                             select new Customer()
                             { 
                                 FirstName = g.Key.FirstName, 
                                 LastName = g.Key.LastName, 
                                 DateofBirth = g.Key.DateofBirth 
                             }).OrderBy( x => x.FirstName )
                             .ThenBy( x=> x.LastName)
                             .ThenBy(x=> x.DateofBirth);
MattC
+1  A: 

Your business rules are somewhat conflicting: Group by Customer Name implies that you won't have multiple occurrences of the same name in the resulting list. Yet your third rule is if there are several results for the same name, then they need to sorted by date of birth. So if by grouping in rule #1 you mean sorting, your query would be merely:

customers.OrderBy(c => c.FirstName).
          ThenBy(c => c.LastName).
          ThenBy(c => c.DateofBirth);

In case you actually mean grouping, rule #3 becomes the criteria for selecting the element in the group - in this case the oldest customer will be chosen for every group:

customers.GroupBy(c => c.FirstName + c.LastName).
          Select(g => g.OrderBy(c => c.DateofBirth).FirstOrDefault()).
          OrderBy(c => c.FirstName).
          ThenBy(c => c.LastName);
Yakimych
Third rule is for case if the list have more the one customer having same name. At that time sort by DateofBirth.
Nirajan Singh
As I mentioned earlier - if you have more than one customer with the same name, they will be grouped into one. But if you don't want to 'merge' them, you don't really need a `GroupBy` - just use `OrderBy(...).ThenBy(...).ThenBy(...)`. What kind of output do you expect, btw? If you want a flat list - use `ToList()` on my queries, in case you want, for example, `List<IGrouping<Customer>>` - apply `ToList()` to Mark Heath's answer.
Yakimych
+1  A: 

It seems slightly strange to group on customer name, but this will do it

var groups = from c in customers 
                let name = c.FirstName + " " + c.LastName
                orderby name ascending, c.DateofBirth ascending
                group c by name into g
                select g;
Mark Heath
You don't really need that space between the names, do you?
Yakimych
@Yakimych well it makes the group.Key look a bit nicer
Mark Heath