How to use LINQ to order within groups
Asked Answered
C

1

19

is it possible (using LINQ preferably) to order a collection which has a natural grouping, within the groups themselves without upsetting the group order?

Let me explain. I have a collection thus:

        List<grpitem> list = new List<grpitem>()
        {
             new grpitem() {groupCode="1", item="a"},
             new grpitem() {groupCode="1", item="b"},
             new grpitem() {groupCode="1", item="c"},
             new grpitem() {groupCode="2", item="a"},
             new grpitem() {groupCode="2", item="c"},
             new grpitem() {groupCode="2", item="b"},
             new grpitem() {groupCode="3", item="c"},
             new grpitem() {groupCode="3", item="b"},
             new grpitem() {groupCode="3", item="a"}
        };

The order in which this arrives (order of groupCode) is determined elsewhere. I need to rearrange the collection so that within each group, elements are ordered by the item value, viz:

             {groupCode="1", item="a"},
             {groupCode="1", item="b"},
             {groupCode="1", item="c"},
             {groupCode="2", item="a"},
             {groupCode="2", item="b"},
             {groupCode="2", item="c"},
             {groupCode="3", item="a"},
             {groupCode="3", item="b"},
             {groupCode="3", item="c"},

The collection could just as equally arrived in the groupCode order "2", "3", "1", or whatever. I must not disturb that - I just need to reorder the elements within each group.

A LINQ query would be really neat! (I'm probably being dim but I haven't yet found one)

I've tried this:

        var reOrdered = (from x in list
                          group x by x.groupCode into groups
                          select groups)
                         .OrderBy(i => from j in i select j.item)
                         .SelectMany(i => i);

but I get an error - "at least one object must IComparable", which puzzles me.

Lastly, this must be C# in .Net3.5, no later.

Curassow answered 20/9, 2013 at 12:51 Comment(6)
You have a SelectMany at the end. Do you need a grouped collection, or are you looking for a flat list?Shrill
Looking for a flat list, ultimately.Curassow
If you are looking for a flat list, you do not need GrouBy at all: use var reOrdered=list.OrderBy(i=>i.groupCode).ThenBy(i=>i.item).Shrill
@haughtonomous: You might want to comment the accept/unaccept action. Can i help?Beefwitted
@dasblinkenlight: He don't want to change the order of the groupCode but the order of the item only.Beefwitted
Actually what you want is to order by 2 columns.Relativistic
B
28
var ordered = list.GroupBy(grp => grp.groupCode)
   .SelectMany(g => g.OrderBy(grp => grp.item));

Here's a demo with garbled sample data.

Beefwitted answered 20/9, 2013 at 12:57 Comment(1)
It was the reuse of grp that I missed.Curassow

© 2022 - 2024 — McMap. All rights reserved.