在C#中,按字符串属性对对象列表排序并获得正确顺序的最佳方法是什么?

在C#中,按字符串属性对对象列表排序并获得正确顺序的最佳方法是什么?,c#,linq,collections,C#,Linq,Collections,我有一个“问题”对象的列表,我想按“优先级”字段对它们进行排序 问题是“Priority”是一个字符串名,比如“HIGH”、“MEDIUM”,所以我没有可以排序的Id。我如何分类并告诉分拣机“高”高于“中”高于“低”?显而易见的方式是: string[] priorities = { "LOW", "MEDIUM", "HIGH" }; var orderedIssues = issues.OrderByDescending (issue => Array.

我有一个“问题”对象的列表,我想按“优先级”字段对它们进行排序


问题是“Priority”是一个字符串名,比如“HIGH”、“MEDIUM”,所以我没有可以排序的Id。我如何分类并告诉分拣机“高”高于“中”高于“低”?

显而易见的方式是:

string[] priorities = {  "LOW", "MEDIUM", "HIGH" };

var orderedIssues = issues.OrderByDescending
              (issue => Array.IndexOf(priorities, issue.Priority));

但请考虑使用枚举:< /P>

public enum Priority
{
    Low,
    Medium,
    High
}

var orderedIssues = issues.OrderByDescending
              (issue => (Priority)Enum.Parse(typeof(Priority), issue.Priority, true));
更好的做法是使用枚举类型作为属性/字段本身的类型,在这种情况下,它与以下内容一样简单(并且不太容易出错):


显而易见的办法是:

string[] priorities = {  "LOW", "MEDIUM", "HIGH" };

var orderedIssues = issues.OrderByDescending
              (issue => Array.IndexOf(priorities, issue.Priority));

但请考虑使用枚举:< /P>

public enum Priority
{
    Low,
    Medium,
    High
}

var orderedIssues = issues.OrderByDescending
              (issue => (Priority)Enum.Parse(typeof(Priority), issue.Priority, true));
更好的做法是使用枚举类型作为属性/字段本身的类型,在这种情况下,它与以下内容一样简单(并且不太容易出错):


最简单的方法可能是:

private static int MapPriority(string priority)
{
  switch(priority.ToUpperInvariant())//skip the case bit if safe
  {
    case "HIGH":
      return 1;
    case "MEDIUM":
      return 2;
    case "LOW":
      return 3;
    default:
      return 4;
  }
}

var sorted = someCollection.OrderBy(i => MapPriority(i.PriorityProperty));
对于db支持的表单,您需要在db中调用一个函数。这只在内存中

有很多可能的值,我会基于字典而不是手工编码。不过,在本例中,我会手动编写三个代码(除非所使用的值可能发生变化,否则会进一步复杂化,使基于字典的方法成为唯一的方法)


如果对大量此类项目进行排序,或者说这类项目太多,我会使用
IComparer
实现,或者让项目本身实现
IComparable
,最简单的方法可能是:

private static int MapPriority(string priority)
{
  switch(priority.ToUpperInvariant())//skip the case bit if safe
  {
    case "HIGH":
      return 1;
    case "MEDIUM":
      return 2;
    case "LOW":
      return 3;
    default:
      return 4;
  }
}

var sorted = someCollection.OrderBy(i => MapPriority(i.PriorityProperty));
对于db支持的表单,您需要在db中调用一个函数。这只在内存中

有很多可能的值,我会基于字典而不是手工编码。不过,在本例中,我会手动编写三个代码(除非所使用的值可能发生变化,否则会进一步复杂化,使基于字典的方法成为唯一的方法)

如果对大量此类项目进行排序,或者说这类项目太多,我会使用
IComparer
实现,或者让项目本身实现
IComparable

类似以下内容:

List<Issue> issues = ...;

var result = issues.OrderBy(x=> x.Priority=="HIGH"?1:x.Priority=="MEDIUM"?2:3);
列出问题=。。。;
var result=issues.OrderBy(x=>x.Priority==“高”?1:x.Priority==“中”?2:3);
类似这样的内容:

List<Issue> issues = ...;

var result = issues.OrderBy(x=> x.Priority=="HIGH"?1:x.Priority=="MEDIUM"?2:3);
列出问题=。。。;
var result=issues.OrderBy(x=>x.Priority==“高”?1:x.Priority==“中”?2:3);

在这种特定情况下,您还可以使用Linq的
OrderBy
方法:

var sortedList = issueList.OrderBy(i=>
                    i.Priority == "HIGH" 
                       ? 1 
                       : i.Priority == "MEDIUM" 
                          ? 2 
                          : 3).ToList();
作为一个单行线,这不会太糟糕。您还可以将字符串按照希望排序的顺序放入数组、列表或字典(或者在字典中包含排序顺序作为值)


使用OrderBy的一个缺点是它不会影响源列表,除非您通过将列表重新分配给结果来告诉它。在所有情况下,它将创建两个额外的集合;OrderBy中内部使用的数组或列表(排序必须知道它们正在排序的整个集合)和ToList()生成的列表。因此,这将需要O(2N)个额外内存,而List.Sort()可能已就位(不确定是否已就位,但它确实使用了通常已就位的快速排序)。

在这种特定情况下,您还可以使用Linq的
OrderBy
方法:

var sortedList = issueList.OrderBy(i=>
                    i.Priority == "HIGH" 
                       ? 1 
                       : i.Priority == "MEDIUM" 
                          ? 2 
                          : 3).ToList();
作为一个单行线,这不会太糟糕。您还可以将字符串按照希望排序的顺序放入数组、列表或字典(或者在字典中包含排序顺序作为值)


使用OrderBy的一个缺点是它不会影响源列表,除非您通过将列表重新分配给结果来告诉它。在所有情况下,它将创建两个额外的集合;OrderBy中内部使用的数组或列表(排序必须知道它们正在排序的整个集合)和ToList()生成的列表。因此,这将需要O(2N)个额外内存,而List.Sort()可能已就位(不确定是否已就位,但它确实使用了通常已就位的快速排序)。

创建一个具有匹配int值的映射字典,并通过从给定字符串中查找对应值进行排序。创建一个具有匹配int值的映射字典,并通过从给定字符串中查找相应的值进行排序。好吧,我并没有进行向下投票,但您正在对用作优先级的字符串数组进行排序。这对任何具有这些优先级的问题对象列表都没有任何影响,正如OP中所述。@KeithS啊,好的观点。没有注意“问题”对象。我会改正的。我更关心的是如何在一行上创建映射……好吧,我并没有否决,但你们正在排序一个字符串数组,这些字符串将用作优先级。这对任何具有这些优先级的问题对象列表都没有任何影响,正如OP中所述。@KeithS啊,好的观点。没有注意“问题”对象。我会改正的。我更关心的是如何在一行上创建映射…有比switch语句更简单更干净的方法。有比switch语句更简单更干净的方法。