2013-12-19 314 views
2

我想按照特定條件對自定義列表進行排序。列表中的每個項目都包含一個名爲「狀態」的屬性,它是一個枚舉,如下所示。列表自定義排序

Empty = 0, Normal = 1, Aged = 2, Dead = 3 

上面指定的值不能更改。當我對我的狀態屬性進行排序時,我希望命令可以像正常,過期,空&死。我不知道如何去做這件事?

下面是我用於不同排序問題的類的示例。不知道我將如何'轉換'這個類來解決我上面的問題?使用在該比較

public static class StatusGoodExtensions 
{ 
    public static int OrderIndex(this StatusGood statusIn) 
    { 
     switch (statusIn) 
     { 
      case StatusGood.Normal: return 0; 
      case StatusGood.Aged: return 1; 
      case StatusGood.Empty: return 2; 
      case StatusGood.Dead: return 3; 
     } 
     throw new NotImplementedException(statusIn.ToString()); 
    } 
} 

,像這樣::

public class SortOrders : IComparer<OrderBlocks.Order> 
{ 
    private bool _sortDescending; 

    public SortOrders(bool sortDescending) 
    { 
     this._sortDescending = sortDescending; 
    } 

    public SortOrders() 
     : this(false) // sort ascending by default 
    { 

    } 

    public int Compare(OrderBlocks.Order x, OrderBlocks.Order y) 
    { 
     if (this._sortDescending) 
     { 
      return y.StatusGood.CompareTo(x.StatusGood); 
     } 
     else 
     { 
      return x.StatusGood.CompareTo(y.StatusGood); 
     } 
    } 
} 
+0

您可以使用LINQ來實現此功能。 –

+0

最容易(但不一定是最有效的)方法很可能使用數組中枚舉值的「索引」:即以'new [] {Normal,Aged,Empty,Dead}'開頭。 OrderBy超過IEnumerable的超級簡單。 – user2864740

回答

1

有很多方式使用OrderBy做到這一點:

鏈接OrderByThenBy CAL LS與你的客戶訂單一起:

var ordered = list.OrderBy(f1 => f1.Status == 3) 
        .ThenBy(f2 => f2.Status == 0) 
        .ThenBy(f3 => f3.Status == 2) 
        .ThenBy(f4 => f4.Status == 1).ToList(); 

或者使用委託開關/箱直列:

var ordered2 = list.OrderBy(foo => 
    { 
     switch (foo.Status) 
     { 
       case (int)Status.Normal: 
        return 0; 
       case (int)Status.Aged: 
        return 1; 
       case (int)Status.Empty: 
        return 2; 
       case (int)Status.Dead: 
        return 3; 
       default: 
        return 0; 
     } 
    }).ToList(); 

均可以得到相同的結果。第一種方法使用已有的枚舉值,第二種方法查看枚舉值並返回一個用於比較的不同整數。

+0

可能在第一個'OrderBy'之後需要'ThenBy'而不是'OrderBy' – Grundy

+0

是的,你是對的。已更新.. – DGibbs

+0

@DGibbs請在複製其他人的答案時添加參考:http://stackoverflow.com/a/20679022/536226 – nima

1

我想創建StatusGood通過之前比較它通過一個轉換功能,即

return x.StatusGood.OrderIndex().CompareTo(y.StatusGood.OrderIndex()); 

通過具有擴展方法,返回訂單的邏輯與排序完全分離,並且可以在別處進行測試或重新使用。

2

這是我會怎麼使用LINQ做到這一點:

 var sorted = myList.OrderBy(x => 
            { 
             switch (x.Status) 
             { 
              case SomethingStatus.Normal: 
               return 0; 
              case SomethingStatus.Aged: 
               return 1; 
              case SomethingStatus.Empty: 
               return 2; 
              case SomethingStatus.Dead: 
               return 3; 
              default: 
               return 10; 
             } 
            }); 
1

通過LINQ擴展的順序採取Func<TSource, TKey> keySelector,這樣你就可以通過自定義排序方法返回的數量級上的一個int值的基礎,你需要:

public enum Status { Empty = 0, Normal = 1, Aged = 2, Dead = 3 } 
public class Item 
{ 
    public Status Status { get; set; } 
    public int OrderedStatus 
    { 
     get 
     { 
      switch (this.Status) 
      { 
       case Status.Normal: return 0; 
       case Status.Aged: return 1; 
       case Status.Empty: return 2; 
       default: return 3; // case Status.Dead 
      } 
     } 
    } 
    public static IEnumerable<Item> OrderByStatus(IEnumerable<Item> items) 
    { 
     return items.OrderBy(item => item.OrderedStatus); 
    } 
}