Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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# 如何对列表进行排序,然后对该列表的子集进行排序_C#_Linq_List_Sorting - Fatal编程技术网

C# 如何对列表进行排序,然后对该列表的子集进行排序

C# 如何对列表进行排序,然后对该列表的子集进行排序,c#,linq,list,sorting,C#,Linq,List,Sorting,我有一套台词。每行都是字段的集合。很容易找到第1列并按其内容排序: _lines = lines.OrderBy(l => l.Fields.Find(f => f.ColumnNumber == 1).Content).ToList(); 但是我该如何对这个列表的子集进行排序呢?我想按f.ColumnNumber==3进行排序,其中(f.ColumnNumber==1) 因此,我的产品系列如下所示: Col1, Col2, Col3 1, data, data 5, data,

我有一套台词。每行都是字段的集合。很容易找到第1列并按其内容排序:

_lines = lines.OrderBy(l => l.Fields.Find(f => f.ColumnNumber == 1).Content).ToList();
但是我该如何对这个列表的子集进行排序呢?我想按f.ColumnNumber==3进行排序,其中(f.ColumnNumber==1)

因此,我的产品系列如下所示:

Col1, Col2, Col3

1, data, data
5, data, data
6, data, Chuck
6, data, Chuck
6, data, Jeffster
6, data, Jeffster
6, data, Grunke
6, data, Gertrude
8, data, data
9, data, data
var data = new []
{
    new Datum() { ID = 1, Cols = new [] { "data", "data", "data", }, },
    new Datum() { ID = 5, Cols = new [] { "data", "data", }, },
    new Datum() { ID = 6, Cols = new [] { "data", "Chuck", }, },
    new Datum() { ID = 6, Cols = new [] { "data", "Chuck", }, },
    new Datum() { ID = 6, Cols = new [] { "data", "Jeffster", }, },
    new Datum() { ID = 6, Cols = new [] { "data", "Jeffster", }, },
    new Datum() { ID = 6, Cols = new [] { "data", "Grunke", }, },
    new Datum() { ID = 6, Cols = new [] { "data", "Gertrude", }, },
    new Datum() { ID = 8, Cols = new [] { "data", "data", }, },
    new Datum() { ID = 9, Cols = new [] { "data", }, },
};
var sorted =
    from d in data
    let key =
        String.Format("{0:0000}", d.ID)
        + (d.ID != 6 ? "" : "-" + d.Cols[1])
    orderby key
    select d;
我想按col1排序,然后只按col1排序,其中col1==6,但按col3排序

有没有办法在c#中做到这一点?我似乎找不到神奇的配方

编辑:

我的示例数据有点过于简化。有些行有3列,其他行有更多或更少的列。因此,当我使用.ThenBy扩展名时,如果我试图在第3列上对行进行次分割,但说第9行只有一列,我会得到一个对象引用,该引用没有设置为对象异常的实例

下面是一个更好的示例数据:

Col1, Col2, Col3, Col4

1, data, data, data
5, data, data
6, data, Chuck
6, data, Chuck
6, data, Jeffster
6, data, Jeffster
6, data, Grunke
6, data, Gertrude
8, data, data
9, data

Code 1 lines have 4 columns.
Code 5 lines have 3.
Code 6 lines have 3 - and I need to sort by col 3 alphabetically.
Code 8 lines have 3 columns.
Code 9 lines have 2.
无法保证该列表已排序。所以我首先需要让行按第一列1-9排序,然后我只需要代码6按第3列排序

编辑2:

我的类结构有点复杂,所以我尽量保持简单,希望这样就足够了,但看起来他的情况并非如此,所以让我与您分享类定义:

public class Field : IField
{
    public FieldSpecification Specification { get; set; }
    public string Content { get; set; }
}

public class FieldSpecification
{
        public int ColumnNumber { get; set; }
        public int Length { get; set; }
        public int StartPosition { get; set; }
        public int EndPosition { get { return StartPosition + Length - 1; } }
        public Justification Justification { get; set; }
        public char PadCharacter { get; set; }
}
然后我有一堆符合ILine接口的行

public interface ILine
{
    List<IField> Fields { get; set; }
    int Credits { get; }
    int Debits { get; }
    BigInteger Hash { get; }
}
公共接口ILine
{
列表字段{get;set;}
整数积分{get;}
int借项{get;}
BigInteger哈希{get;}
}
从技术上讲,我在上面显示了类似field.ColumnNumber的内容,但它应该是field.Specification.ColumnNumber

目标是根据可以更改的规范构建固定宽度的文件。因此,每行都有一个带有规范的字段集合,然后数据可以进入内容,规范可以帮助进行验证:格式化验证

我希望有一种方法可以使用linq对列表子集进行排序,但我可能需要解构最终的行集合,对其进行排序,然后重建集合。我希望避免这种情况。

您可以使用扩展

看看你想要的输出,它看起来很简单

 var output = lines.Select(l => new
    {
        Col1 =  int.Parse(l.Fields.Find(f => f.ColumnNumber == 1).Content),
        Col2 =  l.Fields.Find(f => f.ColumnNumber == 2).Content,
        Col3 =  l.Fields.Find(f => f.ColumnNumber == 3).Content
    }).OrderBy(l => l.Col1).ThenBy(l => l.Col3);
就够了


如果出于某种原因,您只想在
Col1
6
时对子列表进行排序

 var output = lines.Select(l => new
    {
        Col1 =  int.Parse(l.Fields.Find(f => f.ColumnNumber == 1).Content),
        Col2 =  l.Fields.Find(f => f.ColumnNumber == 2).Content,
        Col3 =  l.Fields.Find(f => f.ColumnNumber == 3).Content
    }).OrderBy(l => l.Col1).ThenBy(l => l.Col1 == 6 ? l.Col3 : null);


最后一个警告,根据
字段的类型,可能有更好的方法来解决所有这些问题。

可以通过扩展方法来实现;通常,如果我可以假设您的类定义是这样的,那么这个概念称为。

public class Datum
{
    public int ID { get; set; }
    public string[] Cols { get; set; }
}
然后我可以这样定义数据:

Col1, Col2, Col3

1, data, data
5, data, data
6, data, Chuck
6, data, Chuck
6, data, Jeffster
6, data, Jeffster
6, data, Grunke
6, data, Gertrude
8, data, data
9, data, data
var data = new []
{
    new Datum() { ID = 1, Cols = new [] { "data", "data", "data", }, },
    new Datum() { ID = 5, Cols = new [] { "data", "data", }, },
    new Datum() { ID = 6, Cols = new [] { "data", "Chuck", }, },
    new Datum() { ID = 6, Cols = new [] { "data", "Chuck", }, },
    new Datum() { ID = 6, Cols = new [] { "data", "Jeffster", }, },
    new Datum() { ID = 6, Cols = new [] { "data", "Jeffster", }, },
    new Datum() { ID = 6, Cols = new [] { "data", "Grunke", }, },
    new Datum() { ID = 6, Cols = new [] { "data", "Gertrude", }, },
    new Datum() { ID = 8, Cols = new [] { "data", "data", }, },
    new Datum() { ID = 9, Cols = new [] { "data", }, },
};
var sorted =
    from d in data
    let key =
        String.Format("{0:0000}", d.ID)
        + (d.ID != 6 ? "" : "-" + d.Cols[1])
    orderby key
    select d;
然后我可以这样分类:

Col1, Col2, Col3

1, data, data
5, data, data
6, data, Chuck
6, data, Chuck
6, data, Jeffster
6, data, Jeffster
6, data, Grunke
6, data, Gertrude
8, data, data
9, data, data
var data = new []
{
    new Datum() { ID = 1, Cols = new [] { "data", "data", "data", }, },
    new Datum() { ID = 5, Cols = new [] { "data", "data", }, },
    new Datum() { ID = 6, Cols = new [] { "data", "Chuck", }, },
    new Datum() { ID = 6, Cols = new [] { "data", "Chuck", }, },
    new Datum() { ID = 6, Cols = new [] { "data", "Jeffster", }, },
    new Datum() { ID = 6, Cols = new [] { "data", "Jeffster", }, },
    new Datum() { ID = 6, Cols = new [] { "data", "Grunke", }, },
    new Datum() { ID = 6, Cols = new [] { "data", "Gertrude", }, },
    new Datum() { ID = 8, Cols = new [] { "data", "data", }, },
    new Datum() { ID = 9, Cols = new [] { "data", }, },
};
var sorted =
    from d in data
    let key =
        String.Format("{0:0000}", d.ID)
        + (d.ID != 6 ? "" : "-" + d.Cols[1])
    orderby key
    select d;
我得到以下结果:


这将对所有子集进行排序,而不仅仅是他特别想要排序的子集。是的,这是可行的,尽管我不确定是否有任何保证
OrderBy(x=>null)
保留顺序。另一个选项是按
Col1
分组,然后
在分组上选择many
,如果满足谓词,可以选择在每个组上调用
OrderBy
。诚然,你的解决方案更简洁。请不要在问题标题中包含关于所用语言的信息,除非没有它就没有意义。标签就是为了这个目的。谢谢你。我以后一定会这样做。我不认为您可以通过让我们知道您的数据的类定义来帮助我们?那么,
字段的类型是什么?
?不是您的问题,而是。。。我知道
biginger
将有助于避免冲突,但它永远不会像
int
那样快。你不应该有一个快速的散列,但一个精确的相等。