LINQ如何对一种类型的项进行分组?

4

我有一个列表,其中包含各种派生类。可能会有以下情况:

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

我正在尝试使用LINQ对列表进行半排序,以保持自然顺序,但Class2除外。所有Class2实例应该在第一个Class2出现的地方分组在一起。以下是输出应该像的样子:

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

我真的想不出如何做到这一点...


你是想根据班级名称对列表进行排序吗?我不确定我理解了。 - Ryan Rinaldi
@Ryan:他想把特定类的所有实例移动到第一个实例的位置。请看我的答案。 - SLaks
@Ryan,就像SLaks所说的那样。在这个例子中,类的名称恰好是按顺序排列的,但它可以是任何名称(Foo,Bar,Cheese...)。 - Nelson Rothermel
1个回答

3
你可以这样做:
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();

这将获取第一个 Class2 项目之前的所有项目,然后是所有的 Class2 项目,最后是所有剩余的非 Class2 项目。


1
在 OfType<Class2> 调用之后,您需要一个 .Cast<BaseClass>(),以便可以连接这些列表。 - Martin Harris
我还没有测试过,但你说得对。我仍在努力理解LINQ的强大之处。 - Nelson Rothermel
我认为他并不是明确指Class2,而是指Class2有多个实例(在这种情况下),它们都需要一起出现。其余的将按自然顺序出现。很可能Class3、Class4等也有多个实例。 - Anthony Pegram
脑筋急转弯:如果我想用两个类做同样的事情怎么办?我可以为第二个类复制此查询,但有没有一种“简单”的方法可以在一个查询中完成?如果有帮助的话,类列表可以在List<Type>中。 - Nelson Rothermel
你可以采用Anthony的答案,在orderby之前扩展组,对所需的组进行排序并调整索引。如果您有其他问题,我可以为您解答。 - SLaks
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接