在LINQ C#中使用where条件对列表进行排序

Tuf*_*and 2 c# linq list

我有一个List类型Test,其中有4个propertiesList需要根据某些特定条件进行排序。以下是propertiesof class Test以及示例数据。

class Test
{
    int order;
    string value;
    string dept;
    //..... and some others
}
Run Code Online (Sandbox Code Playgroud)

样本json:

[
   {
      "order":3,
      "value":"ABC",
      "dept":"A"
   },
   {
      "order":2,
      "value":"XYZ",
      "dept":"A"
   },
   {
      "order":1,
      "value":"ABC2",
      "dept":"P"
   },
   {
      "order":4,
      "value":"XYZ2",
      "dept":"P"
   },
   {
      "order":6,
      "value":"ABC3",
      "dept":"Z"
   },
   {
      "order":5,
      "value":"XYZ3",
      "dept":"Z"
   },
]
Run Code Online (Sandbox Code Playgroud)

上面的json数据被加载到一个List<Test>

我的要求是对上面的列表进行排序,就像首先使用dept=P,然后是dept=A,然后dept=Z第二种排序标准是order

我尝试过,OrderBy(x=>x.dept).ThenBy(x=>x.order)但是输出不是预期的。

有什么方法可以指定dept哪个应该首先出现在列表中。

作为一种解决方法,我将List分成多个列表,然后merge在后面将它们分成多个列表sorting,但这并不是我认为的最佳解决方案。

为此,我们还有其他更好且优化的解决方案吗?

Fab*_*jan 5

好吧,您可以使用排序规则创建一个列表:

var orderOfDepts = new List<string> { "P", "A", "Z" };
Run Code Online (Sandbox Code Playgroud)

并使用该列表中元素的索引进行排序:

var sortedList = myList.OrderBy(x=> orderOfDepts.IndexOf(x.dept)).ThenBy(x=> x.order).ToList();
Run Code Online (Sandbox Code Playgroud)

PS如果sortedList收集量不太大,则此解决方案很好,但是如果收集量太大或orderOfDepts列表中有很多排序规则,则可能需要将该算法的整体复杂度从>降低O(N2)O(N*logN)

为此,我们可以利用Dictionarys的快速查找:

int o;
var orderOfDepts = new Dictionary<string, int> 
{
   { "P", 0 },
   { "A", 1 },
   { "Z", 2 }
};

var sortedList = myList
                  .OrderBy(x => orderOfDepts.TryGetValue(x.dept, out o) ? o : int.MaxValue)
                  .ThenBy(x=> x.order)
                  .ToList();
Run Code Online (Sandbox Code Playgroud)

在这里,我们尝试通过key从字典中获取元素x.dept。如果找不到任何内容,则将其放在列表的末尾,否则将使用字典中的值进行排序。

字典的查找为O(1),因此它将大大提高性能,而浪费了构造字典对象所需的时间。对于很少的元素,这样做是不明智的,第一个解决方案会更好,但对于大量数据,此解决方案是不错的。