我在StackOverflow的各种答案中看到,我可以通过类似以下方式来获取列表中第N个最大元素:
var nthFromTop = items.OrderByDescending().Skip(N-1).First();
但是如果列表中存在重复项,这个方法是否还能奏效呢?如果列表中有重复项,有没有方法可以使用LINQ获取第N大的元素(或一组元素)?如果不行,用C#最有效的方法是什么?
var items = new[] {1, 1, 2, 2, 3, 4, 4};
var thirdLargest = items
.GroupBy(x => x)
.OrderByDescending(group => group.Key)
.ElementAt(2);
N
是 2
,则应该返回与第二大项相等的项目组。在您的示例输入中,第二大的项目是 4
,因此它应该返回四个(第一组)的组合。 - Servy要获取与第N大项相等的所有项集,您需要对项目进行分组,对分组进行排序,然后在N为正数时递减N组大小。当N达到零时,您已经找到包含第N大项的组。
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();
}
如果您想获取所有值,且存在重复值,则为第N大的值,请执行以下操作:
编辑
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);
34
。等于34
的项目集是{34, 34, 34}
,因此输出应该是这样的。所以,是的,当N为2时,该集合的输出确实是{34,34.34}
,但不是因为{34,34,34}
是第二大的集合。那只是巧合。为了举一个更好的例子,给定集合{1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,3,4,5,5}
,其中N为3将返回{4}
,因为4
是第三大的项,而{4}
是所有等于4
的项的集合。 - Servy
{1,1,2,2,3,3,4,4}
,并将N
设为2
,那么你期望的输出是什么?你想获取不同的值然后获取第 N 大的值吗?还是你想获取所有等于第 N 大的元素的集合? - Servy