USER_8675309
USER_8675309

Reputation: 893

How can I group by in LINQ and then take first from the group from a sequential set of checks

I have a list of objects and want to take the first that matches a certain criteria, but if that criteria is not met I want to match on the next criteria, and then finally have a "default"

here is my object definition:

public myObject{
    int id { get ; set ;}
    int type { get ; set ;}
    subObjectWithLotsOfProperties { get ; set ;}
 }

and i have my list of objects and want to navigate through it. The following would do what I needed if I knew my types were ordered descending according to my rules

 myList = myList
         .GroupBy(x => x.id,(key, y) => y.OrderByDescending(z=>z.type).FirstOrDefault());

my rule should really be something along the following:

  1. Group my List
  2. for each group take the first item in the list that matches a type of 27
  3. if no item was found matching 27, grab the item with type 14
  4. if no item was found matching 14 or 27, grab the item with type 50
  5. if no item was found matching 14, 27, or 50, just grab any of the list and return that one

Upvotes: 0

Views: 123

Answers (1)

juharr
juharr

Reputation: 32266

Just order on those conditions. Note that false comes before true when ordering.

myList.GroupBy(
    x => x.Id, 
    (key, y) => y.OrderBy(z => z.type != 27)
                 .ThenBy(z => z.type != 14)
                 .ThenBy(z => z.type != 50)
                 .First());

That will order the items with a type of 27 first, then 14, then 50, then everything else. Taking the first will give you one with 27 if there is one, if not one with 14 if there is one, if neither of those then one with 50, and if none just a random one. Note you don't need FirstOrDefault because GroupBy will always create groups with at least one item.

Also if you want you can change the comparisons to == and use OrderByDescending and ThenByDescending instead.

Upvotes: 3

Related Questions