[英]Apply arbitrary number of OrderBy() in LINQ
我写了一个扩展方法,可以采用任意数字或OrderBy()并递归地应用它们。
最好是举一个例子:
public static IEnumerable<User> ApplyOrdering(this IEnumerable<User> users,
int index,
params Func<User, string>[] sorts)
{
if(index == sorts.Length)
return users;
users = users.OrderBy(sorts[index]);
index++;
return users.ApplyOrdering(index, sorts);
}
// And it's called like this:
void Example()
{
var users = GetUnsortedUsers();
var sortedUsers = users.ApplyOrdering(0, u => u.DisplayName,
u => u.Username,
u => u.Email);
}
与其说是一个问题,不如说是我可以通过更好,更优雅的方式来做到这一点吗?
一方面,我不想在方法调用中声明起始索引。 另一个可能的nitpick是必须在最后一次调用.ApplyOrdering()才能返回用户。
你怎么想?! 我希望看到您的C#专家提出的一些聪明的解决方案!
编辑:我知道你们中的一些人会指出,这样做更好,并且更具表现力,只需编写如下查询:
var orderedUsers = users.OrderBy(u => u.DisplayName)
.ThenBy(u => u.Username)
.ThenBy(u => u.Email);
但是在我的方案中,过滤器的数量和类型并不总是相同的,因此我需要一个通用的解决方案,可以容纳任意数量的过滤器。
当前它已损坏 -它将有效地向后应用排序。 我怀疑您想要:
// Slightly more generic, although it's still requiring projections to string...
public static IEnumerable<T> ApplyOrdering<T>(this IEnumerable<T> source,
params Func<T, string>[] sorts)
{
// TODO: Argument validation
if (sorts.Length == 0)
{
return source;
}
IOrderedEnumerable<T> ordered = source.OrderBy(sorts[0]);
foreach (var ordering in sorts.Skip(1))
{
ordered = ordered.ThenBy(ordering);
}
return ordered;
}
您的代码无效,您的列表将仅按您设置的最后一个OrderBy排序。
您必须对第一个使用OrderBy ,对其他一个使用ThenBy 。
这就是我要做的
public static IEnumerable<User> ApplyOrdering(this IEnumerable<User> users, params Func<User, string>[] sorts)
{
var sorted = users.OrderBy(sorts[0]);
for(int i = 1; i < sorts.length; i++)
{
sorted = sorted.ThenBy(sorts[i]);
}
return sorted;
}
我没有花时间测试我的代码,而且我确信有更好的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.