2012-02-16 31 views
3

我在工作中遇到了这个问题,虽然我有解决方案,但我不禁感觉有一种更优雅的方式。 List.IndexOf()的使用对我来说有点难以理解。有没有更好的方式来订购IEnumerable以匹配任意排序?

我必须按信用评级排序BreakdownItems的集合。信用评级不遵循字母顺序,所以我将它们视为只是具有任意的非逻辑顺序。

IEnumerable<BreakdownItem> unsortedCreditRatings = new List<BreakdownItem> 
     { 
      new BreakdownItem{ Name = "CCC", Weight=20d}, 
      new BreakdownItem{ Name = "AA", Weight=20d}, 
      new BreakdownItem{ Name = "AAA", Weight=10d}, 
      new BreakdownItem{ Name = "B", Weight=50d}, 
     }; 

     var sortOrder = new List<string> 
    { "AAA", "AA", "A", "BBB", "BB", "B", "CCC", "below CCC" }; 

     var sortedRatingBreakdown = unsortedCreditRatings 
      .OrderBy(item => sortOrder.IndexOf(item.Name)); 
+1

重复字符串就像评分打开数据完整性问题的可能性。你有没有考虑过你的评价值的枚举? – 2012-02-16 21:56:13

+0

已经有一个枚举了,我没有在这里使用它,因为“低于CCC”不适合Enum。但问题是关于任意排序的更一般的观点 – 2012-02-16 22:02:17

+0

因此,您希望以相同的顺序将任何CCC以下的任何东西集中在一起? – 2012-02-16 22:06:55

回答

5

您可以将信用评级设为枚举而不是字符串吗?然后,您可以为这些枚举值分配正确的排序顺序。

3

正如我提到我的意见之上,具有多个信用评级作为一个字符串可能会导致数据完整性问题,我搬完到enum代替,如:

public enum CreditRatings 
{ 
    AAA, 
    AA, 
    A, 
    BBB, 
    BB, 
    B, 
    CCC, 
    etc 
} 

你,而不是商店在你BreakdownItem,你可以这样做:

var sortedRatingBreakdown = unsortedCreditRatings.OrderBy(item => item.Rating); 

如果必须将它们存储为string,并且不能使用enum你可以考虑使用Dictionary<string, int>或类似的东西来存储您的订购,这样你至少可以得到O(1)查找时间:

var sortedRatingBreakdown = unsortedCreditRatings.OrderBy(item => ratingOrders[item.Name]); 
2

Enumerable.Join保留:

var ratingOrders = new Dictionary<string,int> 
    { 
     { "AAA", 1 }, 
     { "AA", 2 }, 
     { "A", 3 }, 
     etc... 
    }; 

然后你就可以在词典的结果订购第一个(或外部)序列的顺序。如果您不喜欢枚举方法,则可以使用此方法,而无需明确执行OrderBy

var orderedRatings = from item in sortOrder 
        join rating in unsortedCreditRatings 
        on item equals rating.Name 
        select rating; 
相关问题