有没有更好的方法来命令IEnumerable匹配任意顺序?

时间:2012-02-16 21:52:56

标签: c# linq ienumerable

我在工作中遇到了这个问题,虽然我有一个解决方案,但我不禁觉得有一种更优雅的方式。 List.IndexOf()的使用对我来说有点骇人听闻。

我必须按信用评级对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));

3 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分: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 ratingOrders = new Dictionary<string,int>
    {
        { "AAA", 1 },
        { "AA", 2 },
        { "A", 3 },
        etc...
    };

然后你可以按字典的结果订购:

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

答案 2 :(得分:2)

Enumerable.Join保留第一个(或外部)序列的顺序。如果您不热衷于枚举方法,则可以使用此方法,而无需明确地OrderBy

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