我认为这样的东西适合你。
public static IQueryable<T> TopPercentWithTies<T, TKey>(this IOrderedQueryable<T> query, Expression<Func<T, TKey>> groupByExpression, double percent)
{
var groupedQuery = query.GroupBy(groupByExpression);
int numberToTake = groupedQuery.Count() * percent / 100;
return groupedQuery.Take(numberToTake).SelectMany(t => t);
}
我只测试了IEnumerable,所以不确定它是否可以正确地与IQueryable一起使用。在调用TopPercentWithTies()之前,我还对列表进行了排序。
这是我用来测试的代码。
int percent = 50;
var people = new []
{
new { Age = 99, Name = "Adam" },
new { Age = 99, Name = "Andrew" },
new { Age = 89, Name = "Bob" },
new { Age = 50, Name = "Cecil" },
new { Age = 50, Name = "Doug" },
new { Age = 50, Name = "Everett" },
new { Age = 35, Name = "Frank" },
new { Age = 25, Name = "Greg" },
new { Age = 15, Name = "Hank" }
};
var sortedPeople = people.AsQueryable().OrderByDescending(person => person.Age);
var results = sortedPeople.TopPercentWithTies(person => person.Age, percent);
foreach (var person in results)
Console.WriteLine(person);
希望这能对您有所帮助,或者至少指明了正确的方向。您可能需要调整计算numberToTake的逻辑。
TOP n PERCENT WITH TIES
的结果。考虑数据1 2 2 3 3 3 4 4 4 4 ... 100
,它有5050个条目。TOP 1 PERCENT WITH TIES
将返回55行(最高值为10
),而您的函数仅返回1行。 - Ben VoigtWITH TIES
那样工作。正如 Ben Voigt 所述,如果你考虑数据集{3 2 2 1 1 0}
,结果集将会是{3 2 2 1 1}
,而它(与绑定行为一样)应该是{3 2 2}
。 - Saro Taşciyan