Svi*_*ish 11 c# sorting predicate
我有一个需要以特定方式订购的清单.我现在解决了这个问题:
var files = GetFiles()
.OrderByDescending(x => x.Filename.StartsWith("ProjectDescription_"))
.ThenByDescending(x => x.Filename.StartsWith("Budget_"))
.ThenByDescending(x => x.Filename.StartsWith("CV_"))
.ToArray();
Run Code Online (Sandbox Code Playgroud)
这些文件将合并为一个PDF文件,这里的重点是某些文件应该在开头,而其余文件应该在最后.
我想知道是否有更好的方式来编写这种"模式",因为它感觉相当糟糕,如果有更多的情况会变得更加黯然失色.
我想避免的事情,但不确定如何:多次通过列表,StartsWith每个文件的调用次数超过必要,代码多于必要的等等.
基本上我认为我想要一种OrderByPredicates聪明地满足这些标准的东西,其API的使用方式如下:
var predicates = new Func<boolean, File>[] {
x => x.Filename == "First"
x => x.Filename.StartsWith("Foo_"),
x => x.Filename.StartsWith("Bar_"),
};
var files = GetFiles()
.OrderByPredicates(predicates)
.ThenBy(x => x.Filename);
Run Code Online (Sandbox Code Playgroud)
紧凑(除了一点辅助方法)并且易于扩展:
private static readonly string[] Prefixes = {"ProjectDescription_", "Budget_", "CV_"};
public static int PrefixIndex(string name)
{
for (int i = 0; i < Prefixes.Length; i++)
{
if (name.StartsWith(Prefixes[i]))
{
return i;
}
}
return int.MaxValue;
}
// ...
var files = GetFiles().OrderBy(x => PrefixIndex(x.Name));
Run Code Online (Sandbox Code Playgroud)
两个的幂?
var files = GetFiles()
.Order(x => (x.Filename.StartsWith("ProjectDescription_") ? 4 : 0) +
(x.Filename.StartsWith("Budget_") ? 2 : 0) +
(x.Filename.StartsWith("CV_") ? 1 : 0))
.ToArray()
Run Code Online (Sandbox Code Playgroud)
请注意,我删除了降序并为 StartsWith 使用了反向权重。
它可能比你的还要慢,因为这个算法StartsWith每次比较总是需要 3x,而你的算法可能会在第一次“阻塞”StartsWith
请注意,我可能会做类似的事情:
string[] orders = new string[] { "ProjectDescription_", "Budget_", "CV_" };
var files = GetFiles()
.OrderByDescending(x => x.Filename.StartsWith(orders[0]));
for (int i = 1; i < orders.Length; i++) {
files = files.ThenByDescending(x => x.Filename.StartsWith(orders[i]));
}
var files2 = files.ToArray();
Run Code Online (Sandbox Code Playgroud)
通过这种方式,我将订单保存在字符串数组中。为了使代码更容易,我没有检查orders.Length > 0