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

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

问题是“优先级”是一个字符串名称,如“HIGH”,“MEDIUM”,所以我没有我可以排序的ID。 如何排序并告诉分拣机“HIGH”高于“MEDIUM”高于“LOW”?

显而易见的方法是:

string[] priorities = { "LOW", "MEDIUM", "HIGH" }; var orderedIssues = issues.OrderByDescending (issue => Array.IndexOf(priorities, issue.Priority)); 

但是考虑使用枚举:

 public enum Priority { Low, Medium, High } var orderedIssues = issues.OrderByDescending (issue => (Priority)Enum.Parse(typeof(Priority), issue.Priority, true)); 

更好的方法是使用枚举类型作为属性/字段本身的类型,在这种情况下,它就像以下一样简单(并且不易出错):

 var orderedIssues = issues.OrderByDescending(issue => issue.Priority); 

最简单的方法可能是:

 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-backed表单,您需要在可以调用的DB中使用一个函数。 这只是在内存中。

有很多可能的值,我将它基于字典而不是手工代码。 在这种情况下我会手动编写三个代码(除非使用的值可能会改变,进一步的复杂化使得基于字典的方法成为唯一的方法)。

如果对大量此类项目进行排序,或者对此进行大量调用,我将使用IComparer实现,或者让项目本身实现IComparable

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

 var sortedList = issueList.OrderBy(i=> i.Priority == "HIGH" ? 1 : i.Priority == "MEDIUM" ? 2 : 3).ToList(); 

作为单线,这不会太糟糕。 您还可以按照希望对它们进行排序的顺序将字符串放入数组,列表或字典中(或者在字典的情况下将排序顺序包含为值)。

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

 public enum Priority { LOW = 1, MEDIUM = 2, HIGH = 3 } issues.OrderByDescending(issue=>issue.Priority); 

像这样的东西:

 List issues = ...; var result = issues.OrderBy(x=> x.Priority=="HIGH"?1:x.Priority=="MEDIUM"?2:3);