List<T> 扩展方法 First, Second, Third....Nth

List<T> extension method First, Second, Third....Nth

我想访问列表中的第一个、第二个、第三个元素。我可以使用内置的 .First() 方法来访问第一个元素。

我的代码如下:

Dictionary<int, Tuple<int, int>> pList = new Dictionary<int, Tuple<int, int>>();  

var categoryGroups = pList.Values.GroupBy(t => t.Item1);
var highestCount = categoryGroups  
                   .OrderByDescending(g => g.Count())  
                   .Select(g => new { Category = g.Key, Count = g.Count() })  
                   .First();  

var 2ndHighestCount = categoryGroups  
                      .OrderByDescending(g => g.Count())  
                      .Select(g => new { Category = g.Key, Count = g.Count() })  
                      .GetNth(1);  

var 3rdHighestCount = categoryGroups  
                      .OrderByDescending(g => g.Count())  
                      .Select(g => new { Category = g.Key, Count = g.Count() })  
                      .GetNth(2);  

twObjClus.WriteLine("--------------------Cluster Label------------------");
twObjClus.WriteLine("\n");  

twObjClus.WriteLine("Category:{0} Count:{1}",  
                    highestCount.Category, highestCount.Count);  
twObjClus.WriteLine("\n");
twObjClus.WriteLine("Category:{0} Count:{1}",  
                     2ndHighestCount.Category, 2ndHighestCount.Count);  
// Error here i.e. "Can't use 2ndHighestCount.Category here"
twObjClus.WriteLine("\n");  

twObjClus.WriteLine("Category:{0} Count:{1}",  
                     3rdHighestCount.Category, 3rdHighestCount.Count);  
// Error here i.e. "Can't use 3rdHighestCount.Category here"
twObjClus.WriteLine("\n");  

我将扩展方法GetNth()写成:

public static IEnumerable<T> GetNth<T>(this IEnumerable<T> list, int n)
{
   if (n < 0)
      throw new ArgumentOutOfRangeException("n");
      if (n > 0){
         int c = 0;
         foreach (var e in list){
            if (c % n == 0)
            yield return e;
            c++;
         }
      }
}

如果您要查找的是单个对象,则无需自己编写,因为 a built-in method 已经存在。

foo.ElementAt(1)

将为您提供第二个元素等。它的工作方式类似于 First 和 returns 单个对象。

您的 GetNth 方法似乎返回每个第 N 个元素,而不仅仅是索引 N 处的元素。我假设这不是您想要的,因为您说您想要类似于 [=11= 的东西].

由于@Eser 放弃并且不想post 正确 方式作为答案,这里是:

您应该做一次转换,将结果收集到一个数组中,然后从中获取三个元素。您现在的做法会导致代码重复以及多次进行分组和排序,效率低下。

var highestCounts = pList.Values
                    .GroupBy(t => t.Item1)
                    .OrderByDescending(g => g.Count())  
                    .Select(g => new { Category = g.Key, Count = g.Count() })  
                    .Take(3)
                    .ToArray();

// highestCounts[0] is the first count
// highestCounts[1] is the second
// highestCounts[2] is the third
// make sure to handle cases where there are less than 3 items!

仅供参考,如果有一天您只需要第 N 个值而不需要前三个值,则可以使用 .ElementAt 访问任意索引处的值。