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

发布于 2025-01-06 13:51:44 字数 745 浏览 2 评论 0原文

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

I came across this problem at work, and though I have a solution, I can't help feeling there is a more elegant way. The use of List.IndexOf() stands out as a bit hacky to me.

I have to sort a collection of BreakdownItems by credit rating. Credit ratings don't follow alphabetical order so I've treated them as just having some arbitrary, non logical order.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

青春有你 2025-01-13 13:51:44

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

Can you make the credit rating an enum instead of a string? You could then assign those enum values the correct sort order.

瞎闹 2025-01-13 13:51:44

正如我在上面的评论中提到的,将多个信用评级作为字符串可能会导致数据完整性问题,我会将它们移动到 enum 中,例如:

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

而您将其存储在您的 < code>BreakdownItem,您可以这样做:

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

如果您必须将它们存储为字符串,并且不能使用枚举,您可以考虑使用Dictionary 或类似的东西来存储您的排序,以便您至少获得 O(1) 查找时间:

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

然后您可以按字典的结果进行排序:

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

As I alluded in my comment above, having the multiple credit ratings as a string can cause data integrity issues, I'd move those to an enum instead, such as:

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

And you instead store that in your BreakdownItem, you can do:

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

If you must store them as a string, and can't use an enum you could consider using a Dictionary<string, int> or something like that to store your ordering so that you at least get O(1) lookup time:

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

Then you can order by the results of the dictionary:

var sortedRatingBreakdown = unsortedCreditRatings.OrderBy(item => ratingOrders[item.Name]);
任谁 2025-01-13 13:51:44

Enumerable.Join 保留第一个(或外部)序列的顺序。如果您不喜欢枚举方法,则可以使用此方法,而无需显式执行 OrderBy

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

Enumerable.Join preserves the order of the first (or outer) sequence. If you are not keen on the enum approach, you can use this and without needing to do OrderBy explicitly.

var orderedRatings = from item in sortOrder
                     join rating in unsortedCreditRatings
                     on item equals rating.Name
                     select rating;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文