我在工作中遇到了这个问题,虽然我有一个解决方案,但我不禁觉得有一种更优雅的方式。 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));
答案 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;