user12870752
user12870752

Reputation:

Multiple conditional Linq Query

I want to get students who fulfill the following criteria in a WPF application-

  1. Are "passed" the examination
  2. Except first "passed" student in each "group" (Example: Group 1 & 3)
  3. If a group contains only one "passed" student, that student should be omitted (Example: Group 2)
  4. Original grouping should be preserved

Please refer this Students collection as I don't find any option to create tables in StackOverflow.

Code I tried-

 var results = myList
                 .GroupBy(x => x.GroupID)
                 .Select(g => g.OrderBy(x => x.Status)
                 .Where(g => g.Status == "Passed")
                 .Skip(1)
                 .ToList();

The Problem: This doesn't omit the first "passed" student in each group. Instead, it omits only "Richard" (in Group 1) in the entire collection.

Upvotes: 1

Views: 143

Answers (2)

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186668

Well, let's try to apply conditions one after one:

var result = myList
  .Where(student => student.Status == "Passed") // passed only
  .GroupBy(student => student.GroupId)          // grouped by Group Id
  .SelectMany(group => group.Skip(1))           // Skip 1st student in each group 
  .ToList();                                    // if we want to have a List   

If

"If a group contains only one "passed" student, that student should be omitted"

means that we should skip 1st student in each group except groups with single student:

var result = myList
  .Where(student => student.Status == "Passed") 
  .GroupBy(student => student.GroupId)          
  .SelectMany(group => group.Skip(group.Count() > 1 ? 1 : 0))
  .ToList();           

Upvotes: 5

Milney
Milney

Reputation: 6417

Do the Skip in the select so it applies to each group, not the overall results:

 var results = myList.GroupBy(x => x.GroupID)
                    .Where(g => g.Status == "Passed")
                    .Select(g => g.OrderBy(x => x.Status).Skip(1))                 
                    .ToList();

Upvotes: 1

Related Questions