简体   繁体   English

在linq c#中使用where条件对列表进行排序

[英]Sort a list with where condition in linq c#

I have a List of type Test which has 4 properties and the List needs to be sorted with some specific conditions.我有一个类型为TestList ,它有 4 个propertiesList需要根据一些特定条件进行排序。 Below are the properties of class Test and also sample data.下面是class Testproperties以及示例数据。

class Test
{
    int order;
    string value;
    string dept;
    //..... and some others
}

Sample json:示例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"
   },
]

The above json data is loaded to one List<Test> .上面的json数据加载到一个List<Test>

My requirement is to sort the above list like first the items with dept=P , then dept=A and then dept=Z and the second sort criteria is order .我的要求是对上面的列表进行排序,首先是使用dept=P的项目,然后是dept=A ,然后是dept=Z ,第二个排序标准是order

I tried with OrderBy(x=>x.dept).ThenBy(x=>x.order) but the output is not what is expected.我尝试了OrderBy(x=>x.dept).ThenBy(x=>x.order)但输出不是预期的。

Is there any way to specify the dept which should appear first in the list.有没有办法指定应该首先出现在列表中的dept

As a workaround I split the List into multiple lists and then merge them after sorting , but this is not the best solution I guess.作为一种解决方法,我将List拆分为多个列表,然后在sortingmerge它们,但这不是我认为的最佳解决方案。

Do we have any other better and optimized solution for this?我们是否有其他更好和优化的解决方案?

Well, you could create a list with your sorting rules:好吧,您可以使用排序规则创建一个列表:

var orderOfDepts = new List<string> { "P", "A", "Z" };

And use index of elements in that list for sorting:并使用该列表中元素的索引进行排序:

var sortedList = myList.OrderBy(x=> orderOfDepts.IndexOf(x.dept)).ThenBy(x=> x.order).ToList();

PS This solution is good if sortedList collection is not too big, but if it is large or you have many sorting rules in orderOfDepts list then you might want to reduce the overall complexity of this algorithm from > O(N2) to something close to O(N*logN) . PS 如果sortedList集合不是太大,则此解决方案很好,但是如果它很大或者您在orderOfDepts列表中有很多排序规则,那么您可能希望将此算法的整体复杂度从 > O(N2)到接近O(N*logN)

For that we can utilize Dictionary s fast lookups:为此,我们可以利用Dictionary的快速查找:

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();

Here we try to get element from the dictionary by key x.dept .这里我们尝试通过键x.dept从字典中获取元素。 If we don't find anything we put the item to the end of the list otherwise we use the value from the dictionary for sorting.如果我们没有找到任何东西,我们将项目放在列表的末尾,否则我们使用字典中的值进行排序。

Dictionary's lookup is O(1) so it will greatly improve performance in the expense of the time that is required in order to construct the dictionary object.字典的查找是 O(1),因此它将大大提高性能,但代价是构建字典对象所需的时间。 For few elements it would be inadvisable to do it and first solution is better but for large amounts of data this solution is good.对于少数元素,不建议这样做,第一个解决方案更好,但对于大量数据,此解决方案很好。

Try this:尝试这个:

var orderOfDepts = new List<string> { "P", "A", "Z" };

var sortedList =
(
    from x in myList
    join dept in orderOfDepts.Select((name, index) => new { name, index }) on x.dept equals dept.name
    orderby dept.index, x.order
    select x
).ToList();

It should be fairly efficient.它应该是相当有效的。

你可以这样做

var result = _context.OrderBy(p => new { p.dept, p.order}).ToList();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM