tags:

views:

39

answers:

1

I have a List that has various derived classes. I may have something like this:

List<BaseClass> list = new List<BaseClass>() {
  new Class1(),
  new Class2(1),
  new Class3(),
  new Class2(2),
  new Class4()
};

I am trying to use LINQ to semi-sort the list so that the natural order is maintained EXCEPT for Class2. All Class2 instances should be grouped together at the place that the first Class2 occurs. Here is what the output should be like:

List<BaseClass> list = new List<BaseClass>() {
  new Class1(),
  new Class2(1),
  new Class2(2),
  new Class3(),
  new Class4()
};

I can't for the life of me figure out how to do this...

+3  A: 

You can do it like this:

list = list
    .TakeWhile(o => !(o is Class2))
    .Concat(list.Where(o => o is Class2))
    .Concat(
        list.SkipWhile(o => !(o is Class2)).Where(o => !(o is Class2))
    )
    .ToList();

This will take all of the items until the first Class2 item, followed by all of the Class2 items, followed by all remaining non-Class2 items.

SLaks
You'll need a .Cast<BaseClass>() after the OfType<Class2> call so that the lists can be concatenated.
Martin Harris
I haven't tested it yet, but you got it right. I'm still trying to wrap my head around the power of LINQ.
Nelson
@Martin: Yes; I forgot about that.
SLaks
I assume he doesn't mean Class2 explicitly, he means Class2 has multiple instances (in this case), and they all need to appear together. The rest would appear in natural order. It could very well be that there are multiple instances of Class3, Class4, etc.
Anthony Pegram
@Anthony: No. He only wants to move the `Class2` instances.
SLaks
Brain teaser: What if I wanted to do the same thing but with two of the classes? I could duplicate this query for the second class, but any "easy" way of doing it in one query? If it helps, the list of classes can be in a List<Type>.
Nelson
You could take Anthony's answer and expand the groups before the orderby, sorting the desired groups and playing with the indices. If you ask another question, I'll do it for you.
SLaks
Beware that my answer cannot easily generalize to multiple types. (You'd have to know which one comes first)
SLaks
Ahh. Well, this is an odd (to me) requirement. I wonder if (@Nelson) you can provide some specifics as to the problem, just to satisfy my own intellectual curiosity.
Anthony Pegram
@SLaks: Ok, here's a new, more "generic" question: http://stackoverflow.com/questions/2835492/linq-group-specific-types-of-classes
Nelson
@Anthony: I have a list of classes which have a Dictionary<string, string> ToDictionary() method. I use that dictionary to generate an e-mail with sections (each class) and key/value pairs. Most of the sections should be separate, but there is one instance where it really doesn't make sense to keep them separate and thus should be merged.
Nelson