我有一个按考试点排序的列表,我希望得到这个列表的前N个元素.
如果N(th)和N 1(th)学生具有相同的考试点,则列表必须同时具有它们.
如果N(th)和N 1(th)学生具有相同的考试点,则列表必须同时具有它们.
例如,我有一个这样的列表:
john. 80 mike. 75 james. 70 ashley. 70 kate. 60
前三名应该回到约翰,迈克,詹姆斯,阿什利
我试过Take(),但它只返回john,mike,james
英语不是我的主要语言,对不起,如果我说不出来的话
谢谢
解决方法
这是一个一次通过的实现:
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; } } } }
用法示例:
var data = new[] { new { name = "john",value = 80 },new { name = "mike",value = 75 },new { name = "james",value = 70 },new { name = "ashley",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); }