【问题标题】:In C#, how can I sort a collection of objects by multiple fields of that object?在 C# 中,如何按对象的多个字段对对象集合进行排序?
【发布时间】:2016-04-01 08:42:07
【问题描述】:
我有一个项目对象列表,我想使用项目对象中的几个不同字段对集合进行排序。
IEnumerable<Project> list = GetProjectList();
public class Project
{
public DateTime? Date;
public string ImportanceLevel;
}
我先想
- 按日期字段排序(较早的日期应位于列表顶部,而不是较远的未来日期),这些应显示在任何没有日期的项目之前。
- 对于没有设置日期的项目,我想按 ImportanceLevel(可以是 3 个字符串之一(Low、Medium 或 High)之一,其中先是 High,然后是 Medium,然后是 Low
如果这些是整数值,我很感激这会更好,但不幸的是它们现在被存储为字符串。
【问题讨论】:
标签:
c#
linq
sorting
collections
【解决方案1】:
这会起作用
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;
});
【解决方案2】:
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;
}
});
【解决方案3】:
一个选项是
var sorted = list.OrderBy(l => l.Date.HasValue ? l.Date : DateTime.MaxValue)
.ThenBy(l => l.ImportanceLevel == "High" ? 1 :
(l.ImportanceLevel == "Medium" ? 2 : 3));
在这里,它会做你想做的事,它还会按重要性对具有相同日期的项目进行排序。
或者,
var sorted2 = list.OrderBy(l => l.Date.HasValue ?
int.Parse(l.Date.Value.ToString("yyyyMMdd")) :
(l.ImportanceLevel == "High" ?
100000001 :
(l.ImportanceLevel == "Medium" ? 100000002 : 100000003)));
在哪里,它不会按重要性对有日期的项目进行排序。
【解决方案4】:
//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);
// 现在你可以使用 projectsWithDate 集合了。