C# 在 LINQ 中升序/降序 - 可以通过参数更改顺序吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/388708/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ascending/descending in LINQ - can one change the order via parameter?
提问by Johannes
I have a method which is given the parameter "bool sortAscending". Now I want to use LINQ to create sorted list depending on this parameter. I got then this:
我有一个方法,它被赋予参数“bool sortAscending”。现在我想使用 LINQ 根据此参数创建排序列表。我得到了这个:
var ascendingQuery = from data in dataList
orderby data.Property ascending
select data;
var descendingQuery = from data in dataList
orderby data.Property descending
select data;
As you can see, both queries differ only in "ascending" resp. "descending". I'd like to merge both queries, but I don't know how. Does anyone have the answer?
如您所见,这两个查询仅在“升序”方面有所不同。“下降”。我想合并两个查询,但我不知道如何。有人有答案吗?
采纳答案by Jon Skeet
You can easily create your own extension method on IEnumerable or IQueryable:
您可以轻松地在 IEnumerable 或 IQueryable 上创建自己的扩展方法:
public static IOrderedEnumerable<TSource> OrderByWithDirection<TSource,TKey>
(this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
bool descending)
{
return descending ? source.OrderByDescending(keySelector)
: source.OrderBy(keySelector);
}
public static IOrderedQueryable<TSource> OrderByWithDirection<TSource,TKey>
(this IQueryable<TSource> source,
Expression<Func<TSource, TKey>> keySelector,
bool descending)
{
return descending ? source.OrderByDescending(keySelector)
: source.OrderBy(keySelector);
}
Yes, you lose the ability to use a query expression here - but frankly I don't think you're actually benefiting from a query expression anyway in this case. Query expressions are great for complex things, but if you're only doing a single operation it's simpler to just put that one operation:
是的,您在这里失去了使用查询表达式的能力 - 但坦率地说,我认为在这种情况下您实际上并没有从查询表达式中受益。查询表达式非常适合处理复杂的事情,但如果您只执行单个操作,则只执行一个操作会更简单:
var query = dataList.OrderByWithDirection(x => x.Property, direction);
回答by Marc Gravell
In terms of how this is implemented, this changes the method- from OrderBy/ThenBy to OrderByDescending/ThenByDescending. However, you can apply the sort separately to the main query...
就如何实现而言,这改变了方法- 从 OrderBy/ThenBy 到 OrderByDescending/ThenByDescending。但是,您可以将排序单独应用于主查询...
var qry = from .... // or just dataList.AsEnumerable()/AsQueryable()
if(sortAscending) {
qry = qry.OrderBy(x=>x.Property);
} else {
qry = qry.OrderByDescending(x=>x.Property);
}
Any use? You can create the entire "order" dynamically, but it is more involved...
有什么用吗?您可以动态创建整个“订单”,但它涉及更多......
Another trick (mainly appropriate to LINQ-to-Objects) is to use a multiplier, of -1/1. This is only really useful for numeric data, but is a cheeky way of achieving the same outcome.
另一个技巧(主要适用于 LINQ-to-Objects)是使用 -1/1 的乘数。这仅对数字数据真正有用,但却是实现相同结果的一种厚颜无耻的方式。
回答by sports
What about ordering desc by the desired property,
按所需属性排序 desc 怎么样,
blah = blah.OrderByDescending(x => x.Property);
And then doing something like
然后做类似的事情
if (!descending)
{
blah = blah.Reverse()
}
else
{
// Already sorted desc ;)
}
Is it Reverse() too slow?
Reverse() 是不是太慢了?
回答by ehh
In addition to the beautiful solution given by @Jon Skeet, I also needed ThenBy and ThenByDescending, so I am adding it based on his solution:
除了@Jon Skeet 给出的漂亮解决方案,我还需要 ThenBy 和 ThenByDescending,所以我根据他的解决方案添加了它:
public static IOrderedEnumerable<TSource> ThenByWithDirection<TSource, TKey>(
this IOrderedEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
bool descending)
{
return descending ?
source.ThenByDescending(keySelector) :
source.ThenBy(keySelector);
}