列出自定义排序

时间:2013-12-19 10:08:09

标签: c# sorting

我想按照特定条件对自定义列表进行排序。我列表中的每个项目都包含一个名为“Status”的属性,它是一个枚举,如下所示。

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

无法更改上面指定的值。当我对我的状态属性进行排序时,我希望顺序为Normal,Aged,Empty&死。我不知道如何最好地解决这个问题?

以下是我用于不同排序问题的类的示例。我不确定如何“转换”这个类以解决上面的问题?

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

4 个答案:

答案 0 :(得分: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 :(得分:1)

我会在比较之前创建一个StatusGood传递的转换函数,即:

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

在比较中使用,如下:

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

通过扩展方法,返回订单的逻辑与排序完全分开,可以在其他地方进行测试或重复使用。

答案 2 :(得分: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);
    }
}

答案 3 :(得分:1)

使用OrderBy有很多方法可以做到这一点:

OrderByThenBy通话与您的自定义订单联系起来:

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

两者都给出相同的结果。第一种方法使用您已有的枚举值,第二种方法查看枚举值并返回另一个用于比较的整数。