简体   繁体   English

在C#中,如何按该对象的多个字段对对象集合进行排序?

[英]In C#, how can I sort a collection of objects by multiple fields of that object?

I have a list of project objects and I want to sort the collection by using a few different fields in the project object. 我有一个项目对象列表,我想通过使用项目对象中的几个不同字段来对集合进行排序。

IEnumerable<Project> list = GetProjectList();

public class Project
{
      public DateTime? Date;
      public string ImportanceLevel;
}  

I first want to 我首先要

  • Sort by the date field (sooner dates should be at the top of the list versus dates farther out in the future) and those should show up before any item without a date. 按日期字段排序(较早的日期应该在列表的顶部,而较远的日期应该在列表的顶部),这些日期应该显示在没有日期的任何项目之前。
  • For the items that don't have Dates set them i want to sort by ImportanceLevel (which can be one of 3 strings (Low, Medium or High) where High would go first and then Medium and then Low 对于没有日期设置的项目,我想按ImportanceLevel排序(可以是3个字符串(低,中或高)之一,其中高将首先出现,然后是中,然后是低

I appreciate this would be better if these were integer values but unfortunately they are stored as strings right now). 我很欣赏如果这些是整数值会更好,但不幸的是它们现在存储为字符串。

One option is 一种选择是

var sorted = list.OrderBy(l => l.Date.HasValue ? l.Date : DateTime.MaxValue)
    .ThenBy(l => l.ImportanceLevel == "High" ? 1 : 
                    (l.ImportanceLevel == "Medium" ? 2 : 3));

Here, it will do what you want, also it'll sort the projects with same date, by importance. 在这里,它会做您想做的事,还会按重要性对具有相同日期的项目进行排序。

Or, 要么,

var sorted2 = list.OrderBy(l => l.Date.HasValue ? 
                  int.Parse(l.Date.Value.ToString("yyyyMMdd")) :
                  (l.ImportanceLevel == "High" ? 
                      100000001 :
                      (l.ImportanceLevel == "Medium" ? 100000002 : 100000003)));

Where, it'll not sort the projects which have date, by importance. 在哪里,它不会按重要性对有日期的项目进行排序。

//Order by the projects with Date
var projectsWithDate = list.Where(d => d.Date != null)
           .OrderBy(s => s.Date).ToList();

// Projects without Dates

var withoutdate = list.Where(d => d.Date == null)
    .OrderBy(g =>
    {
        if (g.ImportanceLevel == "High")
            return 1;
        if (g.ImportanceLevel == "Medium")
            return 2;
        if (g.ImportanceLevel == "Low")
            return 3;

        return 0;
    })
    .ToList();

//Add the second list to first.
projectsWithDate.AddRange(withoutdate);

// Now you can use projectsWithDate collection. //现在,您可以使用projectsWithDate集合。

This will work 这会起作用

var orderedList = list
                .OrderBy(p => p.Date)
                .ThenByDescending(p =>
                {
                    if (p.ImportanceLevel == "Low")
                        return 1;
                    if (p.ImportanceLevel == "Medium")
                        return 2;
                    if (p.ImportanceLevel == "Hight")
                        return 3;
                    return 0;
                });
    public class Project    
    {
        public DateTime? Date;
        public string ImportanceLevel;
    }

    var sortedProejcts =
            projects.OrderByDescending(p => p.Date.HasValue)
            .ThenBy(p => Math.Abs(DateTime.Now.CompareTo(p.Date ?? DateTime.MaxValue)))
            .ThenByDescending(
                p =>
                {
                    switch (p.ImportanceLevel)
                    {
                        case "Low":
                            return 1;
                        case "Medium":
                            return 2;
                        case "High":
                            return 3;
                        default:
                            return 0;
                    }
                });

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

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