In C#, what is the best way to sort a list of objects by a string property and get correct order?

前端 未结 5 800
不知归路
不知归路 2020-12-22 02:49

I have a list of \"Issue\" objects and i want to sort them by the \"Priority\" field.

The issue is that \"Priority\" is a string name like \"HIGH\", \"MEDIUM\" so i

相关标签:
5条回答
  • 2020-12-22 03:29

    The obvious way would be:

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

    But consider using an enumeration:

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

    Even better would be using the enumeration type as the type of the property / field itself, in which case it's as simple (and less prone to error) as:

    var orderedIssues = issues.OrderByDescending(issue => issue.Priority);
    
    0 讨论(0)
  • 2020-12-22 03:31

    The easiest way would probably be like:

    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));
    

    With a db-backed form you'll need a function in the DB you can call into. This is in-memory only.

    With lots of possible values, I'd base it on a dictionary rather than hand-code. I'd hand-code for three as in this case though (unless the values used could change, a further complication making dictionary-based approaches the only way).

    If sorting a serious number of such items, or calling this a lot, I'd go with an IComparer<T> implementation, or have the item itself implement IComparable<T>.

    0 讨论(0)
  • 2020-12-22 03:33

    Something like this:

    List<Issue> issues = ...;
    
    var result = issues.OrderBy(x=> x.Priority=="HIGH"?1:x.Priority=="MEDIUM"?2:3);
    
    0 讨论(0)
  • 2020-12-22 03:50
    public enum Priority
    {
        LOW = 1,
        MEDIUM = 2,
        HIGH = 3
    }
    
    issues.OrderByDescending(issue=>issue.Priority);
    
    0 讨论(0)
  • 2020-12-22 03:51

    You could, in this specific case, also use Linq's OrderBy method:

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

    As a one-liner this wouldn't be too bad. You could also put the strings into an array, list or Dictionary in the order you want them sorted (or containing the sort order as the Value in the case of the Dictionary).

    The one downside of using OrderBy is that it doesn't affect the source List unless you tell it to by reassigning the List to the result. In all cases, it will create two additional collections; an internally-used array or list within OrderBy (sorts have to have knowledge of the entire collection they're sorting) and the List produced by ToList(). So, this will require O(2N) additional memory, while List.Sort() could be in-place (not sure if it actually is, but it does use QuickSort which is normally in-place).

    0 讨论(0)
提交回复
热议问题