如何使用LinQ获取列表的前N个元素?

Ahm*_*e90 6 c# linq

我有一个按考试点排序的列表,我希望得到这个列表的前N个元素.
如果N(th)和N + 1(th)学生具有相同的考试点,则列表必须同时具有它们.

例如,我有一个这样的列表:

john.   80  
mike.   75  
james.  70  
ashley. 70
kate.   60
Run Code Online (Sandbox Code Playgroud)

前三名应该返回john, mike, james, ashley
我试过Take()但它只返回john, mike, james

英语不是我的主要语言,对不起,如果我说不出来,
谢谢

Mar*_*ell 10

这是一个一次通过的实现:

public static IEnumerable<TSource> TopWithTies<TSource, TValue>(
    this IEnumerable<TSource> source,
    int count,
    Func<TSource, TValue> selector)
{
    if (source == null) throw new ArgumentNullException("source");
    if (selector == null) throw new ArgumentNullException("selector");
    if (count < 0) throw new ArgumentOutOfRangeException("count");
    if (count == 0) yield break;
    using(var iter = source.OrderByDescending(selector).GetEnumerator())
    {
        if(iter.MoveNext())
        {
            yield return iter.Current;
            while (--count >= 0)
            {
                if(!iter.MoveNext()) yield break;
                yield return iter.Current;    
            }
            var lastVal = selector(iter.Current);
            var eq = EqualityComparer<TValue>.Default;
            while(iter.MoveNext() && eq.Equals(lastVal, selector(iter.Current)))
            {
                yield return iter.Current;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

var data = new[]
{
    new { name = "john", value = 80 },
    new { name = "mike", value = 75 },
    new { name = "james", value = 70 },
    new { name = "ashley", value = 70 },
    new { name = "kate", value = 60 }
};
var top = data.TopWithTies(3, x => x.value).ToList();
foreach(var row in top)
{
    Console.WriteLine("{0}: {1}", row.name, row.value);
}
Run Code Online (Sandbox Code Playgroud)


Tim*_*ter 3

如果两个以上的学生成绩相同怎么办?你会把它们全部带走吗?操作员:是的

您可以按点分组,然后使用OrderByDescending+ Take+ SelectMany

var topThreePoints = users.GroupBy(u => u.Points)
                          .OrderByDescending(g => g.Key)
                          .Take(3)
                          .SelectMany(g => g);
Run Code Online (Sandbox Code Playgroud)

  • 不过,这需要前 3 组 - 如果第一组有 200 个项目,则您不会从任何其他组中获取任何项目 (3认同)