[英]In C#, what is the best way to sort a list of objects by a string property and get correct order?
我有一個“問題”對象的列表,我想按“優先級”字段對它們進行排序。
問題是“優先級”是一個字符串名稱,例如“ HIGH”,“ MEDIUM”,因此我沒有可以排序的ID。 如何分類並告訴分揀機“ HIGH”高於“ MEDIUM”,而“ 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));
使用數據庫支持的表單,您將需要在數據庫中調用一個函數。 這僅在內存中。
有很多可能的值,我將其基於字典而不是手工編碼。 不過,在這種情況下,我會手動編碼三個(除非使用的值可以更改,否則進一步的復雜性將使基於字典的方法成為唯一方法)。
如果要對大量此類項目進行排序或進行大量調用,則可以使用IComparer<T>
實現,或者讓項目本身實現IComparable<T>
。
在這種特定情況下,您還可以使用Linq的OrderBy
方法:
var sortedList = issueList.OrderBy(i=>
i.Priority == "HIGH"
? 1
: i.Priority == "MEDIUM"
? 2
: 3).ToList();
作為一線客,這還不錯。 您還可以按照想要對字符串進行排序的順序(或在字典的情況下,將排序順序作為Value包含在數組中)將其放入數組,列表或Dictionary中。
使用OrderBy的一個缺點是,除非您通過將List重新分配給結果來告知它,否則它不會影響源List。 在所有情況下,它將創建兩個額外的集合。 一個內部使用的數組或OrderBy中的列表(排序必須了解他們正在排序的整個集合)以及ToList()生成的List。 因此,這將需要O(2N)額外的內存,而List.Sort()可能就在原地(不確定是否確實在,但它確實使用了通常在原地的QuickSort)。
public enum Priority
{
LOW = 1,
MEDIUM = 2,
HIGH = 3
}
issues.OrderByDescending(issue=>issue.Priority);
像這樣:
List<Issue> issues = ...;
var result = issues.OrderBy(x=> x.Priority=="HIGH"?1:x.Priority=="MEDIUM"?2:3);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.