Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ-特定于组的类类型_C#_.net_Linq - Fatal编程技术网

C# LINQ-特定于组的类类型

C# LINQ-特定于组的类类型,c#,.net,linq,C#,.net,Linq,这个问题类似于,但处理方式更一般 我有一个包含各种派生类的列表。我可能有这样的想法: 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) }; List List=新列表(){ 新类别1(1),

这个问题类似于,但处理方式更一般

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

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)
};
List List=新列表(){
新类别1(1),
新类别2(1),
新类别1(2),
新类别3(1),
新类别2(2),
新类别4(1),
新类别3(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),
};
List List=新列表(){
新类别1(1),
新类别1(2),
新类别2(1),
新类别3(1),
新类别3(2)
新类别2(2),
新类别4(1),
};

Edit:Oops,忘了说这个结果是假设的(Class1和Class3)。GroupThisType==true

OrderBy LINQ方法可以接受IComparer通用接口。您可以使用它来实现自定义排序算法。我不知道默认的顺序可以处理您试图做的事情(这取决于您需要实现的所有规则)。我假设你的类实际上没有命名为Class1,Class2,在类型名中有顺序

嗯。

像这样:

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个项目


您可以用
typesToGroup.Contains(g.Key)
替换
g.First().GroupThisType
,这里有一个使用两个过程的解决方案:在第一个过程中,我构建了一个包含所有应该分组的字典。在第二个示例中,我使用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}));

他希望保留原始顺序,但将某些类型的所有项目移动到第一次出现的位置。使用
IComparer
@SLaks是不可能做到的:是的,我唯一想的是GroupThis类型会被复制,理论上对于同一类的实例可能会不同。我会创建一个这些类型的列表组,但我不知道这些类型提前(插件类型系统)。静态变量可能最有意义。它不会改变你的答案……除非我想在基类中使用它,否则我不能使它成为静态的,否则我只有一个该变量的实例。哦,好吧……我开始认为更传统的方法更容易理解:)而且,通过做I*10000,你限制了总共可以有多少个项目。我猜我是一个整数,因此2147483647/10000=214748最大项。仍然远远超过我所拥有的。
I
是一个
int
,但是你可以将它转换为
长的
。但是它会的,我不是在字典上迭代,而是在原始列表上迭代,使用字典只找到相关的组。但是它确实依赖于GroupBy的有序性。。。幸运的是,MSDN证实了这一点。