我想按照特定条件对自定义列表进行排序。我列表中的每个项目都包含一个名为“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);
}
}
}
答案 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有很多方法可以做到这一点:
将OrderBy
和ThenBy
通话与您的自定义订单联系起来:
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();
两者都给出相同的结果。第一种方法使用您已有的枚举值,第二种方法查看枚举值并返回另一个用于比较的整数。