如何使用LINQ从具有重复项的列表中获取第N个最大元素?

时间:2014-06-27 15:50:50

标签: c# linq

我在各种StackOverflow答案中看到,我可以通过执行类似

的操作获得列表中的第N个最大元素
var nthFromTop = items.OrderByDescending().Skip(N-1).First();

但如果列表中没有重复内容,那么这只会起作用吗?如果列表包含重复项,是否有办法使用LINQ获取第N个最大元素(或元素集)?如果没有,那么在C#中最有效的方法是什么?

4 个答案:

答案 0 :(得分:3)

如果您想获得所有元素的集合,请使用GroupBy

 var items = new[] {1, 1, 2, 2, 3, 4, 4};
 var thirdLargest = items
   .GroupBy(x => x)
   .OrderByDescending(group => group.Key)
   .ElementAt(2);

答案 1 :(得分:2)

要使所有项目的集合等于您需要对项目进行分组的第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();
}

答案 2 :(得分:0)

如果您想避免重复,请按分组怎么样?

答案 3 :(得分:0)

如果您想要获得重复的第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);