要使用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);
因此,列表将始终按Item1排序,并有条件地按Item2和/或Item3排序。
如何在C#中实现这一目标?没有Linq的解决方案也很受欢迎。
答案 0 :(得分:7)
只需使用
var orderedItems = list.OrderBy(_ => 1);
这为您提供了默认(非)排序,并允许您在之后使用ThenBy
添加任意数量的其他排序。
修改强>
Tim指出,这确实会带来性能损失 - 似乎默认的LINQ-to-Objects提供商不够智能,无法重建排序以摆脱&#34;非订购&#34 ;。如果您的列表很小,这不是问题,但是如果它花费的时间不可忽略,那么您可能想要这么做。
例如,您可以使用辅助方法,如
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);
}
这与你正在做的完全相同,但除非您正在处理以前订购过的可枚举,否则它会去以同样的方式工作。
答案 1 :(得分:2)
使用IOrderedEnumerable
代替列表和if ... else
:
IOrderedEnumerable<Tuple<int, string, DateTime>> orderedItems = null;
if (sortByDateTime)
orderedItems = list.OrderBy(listItem => listItem.Item3);
else if (sortByString)
orderedItems = list.OrderBy(listItem => listItem.Item2);
orderedItems = orderedItems.ThenBy(listItem => listItem.Item1);
list = orderedItems.ToList();
答案 2 :(得分:-1)
您需要使用状态机,如下面的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
enum State
{
One,
Two,
}
static void Main(string[] args)
{
State state = State.A;
switch (state)
{
case State.One:
//Order by item one
state = State.Two;
break;
case State.Two:
//Order by item two or three
state = State.One;
break;
}
}
}
}