要使用Linq订购列表,我们必须OrderBy首先调用ThenBy对下级排序的结果.
我现在处于一种情况,我不知道顶级订购.我有一份应该有条件地应用的订单清单.
像这样:
var list = new List<Tuple<int, string, DateTime>>();
list.Add(new Tuple<int, string, DateTime>(1, "B", new DateTime(2020, 1, 1)));
list.Add(new Tuple<int, string, DateTime>(2, "A", new DateTime(2000, 1, 1)));
list.Add(new Tuple<int, string, DateTime>(3, "C", new DateTime(1900, 1, 1)));
var orderedList = list;
if (sortByString)
{
orderdedList = orderedList.ThenBy(listItem => listItem.Item2);
}
if (sortByDateTime)
{
orderedList = orderedList.ThenBy(listItem => listItem.Item3);
}
orderList = orderedList.ThenBy(listItem => listItem.Item1);
Run Code Online (Sandbox Code Playgroud)
因此,列表将始终按Item1排序,并有条件地按Item2和/或Item3排序.
如何在C#中实现这一目标?没有Linq的解决方案也是受欢迎的.
只是用
var orderedItems = list.OrderBy(_ => 1);
Run Code Online (Sandbox Code Playgroud)
这为您提供了默认(非)排序,并允许您使用just后添加任意数量的其他排序ThenBy.
编辑:
Tim指出,这确实会带来性能损失 - 似乎默认的LINQ-to-Objects提供程序不够智能,无法重建排序以摆脱"非排序".如果您的列表很小,这不是问题,但如果它花费不可忽略的时间,您可能想要以艰难的方式执行此操作.
例如,您可以使用类似的辅助方法
public static IEnumerable<T> AppendOrdering<T, U>(this IEnumerable<T> @this,
Func<T, U> selector)
{
if (@this is IOrderedEnumerable<T>) return @this.ThenBy(selector);
return @this.OrderBy(selector);
}
Run Code Online (Sandbox Code Playgroud)
这与你正在做的不完全相同,但除非你正在处理之前订购的可枚举,否则它将以相同的方式工作.