代码之家  ›  专栏  ›  技术社区  ›  Nelson Rothermel

LINQ-特定于组的类类型

  •  5
  • Nelson Rothermel  · 技术社区  · 15 年前

    这个问题类似于 LINQ group one type of item 但处理方式更一般。

    我有一个包含各种派生类的列表。我可能有这样的东西:

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

    我尝试使用Linq对列表进行半排序,以便维护自然顺序,但某些类的base.groupThisType==true除外。具有groupThisType的所有类都应在同一类型的第一个类出现的位置分组在一起。下面是输出应该是什么样子的:

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

    编辑: 哎呀,忘了说这个结果是假设的(Class1和Class3)。GroupThisType==true

    3 回复  |  直到 15 年前
        1
  •  1
  •   SLaks    15 年前

    这样地:

    list = list.Select((o, i) => new { Index = i * 10000, Value = o })
               .GroupBy(q => q.GetType())
               .SelectMany(g => {
                   if (g.First().GroupThisType)
                       return g.Select((q, i) => 
                           new { Index = g.First().Index + i, Value = q.Value }
                       );
                   else
                       return g;
               })
               .OrderBy(q => q.Index)
               .Select(q => q.Value)
               .ToList();
    

    这个 i * 10000 允许在任意两个项目之间插入一个组中最多10000个项目。

    你可以代替 g.First().GroupThisType 具有 typesToGroup.Contains(g.Key) .

        2
  •  1
  •   Ian Mercer    15 年前

    这里有一个使用两个过程的解决方案:首先,我构建一个包含所有应该分组的字典。在第二个例子中,我使用selectmany来收集不与排序序列进行排序的元素,对于任何进行排序的元素中的第一个。

    // Build a dictionary of the items that group
    var onesToGroup = list.Where(x => x.GroupThisClass)
                                .GroupBy(x => x.GetType())
                                .ToDictionary(x => x.Key, x => x.AsEnumerable());
    
    var results = list.SelectMany(x => x.GroupThisClass ?
                                 (onesToGroup[x.GetType()].First() == x ? onesToGroup[x.GetType()] : (new BaseClass[]{}))
                                                    : (new []{x}));
    
        3
  •  0
  •   Brian Mains    15 年前

    orderby-linq方法可以接受IComparer通用接口。您可以使用它来实现您的自定义排序算法。我不知道默认排序可以处理您要做的事情(这取决于您需要实现的所有规则)。我假设你的类实际上不是以类型名排序的class1,class2命名的?

    Hth.