问题
I've seen in various StackOverflow answers that I can get the Nth largest element in a list by doing something like
var nthFromTop = items.OrderByDescending().Skip(N-1).First();
But wouldn't this only work if there are no duplicates in the list? If the list contains duplicates, is there a way to get the Nth largest element (or set of elements) using LINQ? If not, what would be the most efficient way to do this in C#?
回答1:
To get the set of all items equal to the Nth largest item you'll need to group the items, order the groups, and then decrement N by the group size while N is positive. When N reaches zero, you've hit the group containing the Nth largest item.
public static IEnumerable<T> Foo<T>(this IEnumerable<T> source, int n)
{
return source.GroupBy(x => x)
.OrderByDescending(group => group.Key)
.SkipWhile(group =>
{
n -= group.Count();
return n > 0;
})
.First();
}
回答2:
If you want to get a set of all the elements, use GroupBy
var items = new[] {1, 1, 2, 2, 3, 4, 4};
var thirdLargest = items
.GroupBy(x => x)
.OrderByDescending(group => group.Key)
.ElementAt(2);
回答3:
If you would like to avoid duplicates, how about using group by?
回答4:
If you want to get all values that are the Nth largest if there are duplicates do this:
EDIT
List<int> ints = new List<int>()
{
1,2,5,8,12,34,12,52,34
};
int NthLargest = 1;
var queryresult = ints
.GroupBy(e => e)
.OrderByDescending(f => f.Count())
.ThenByDescending(k => k.Key)
.ElementAt(NthLargest - 1);
来源:https://stackoverflow.com/questions/24455950/how-do-i-get-the-nth-largest-element-from-a-list-with-duplicates-using-linq