2014-02-25 39 views
0

內我有一個整數列表:LINQ限量結果

List<int> a = new List<int>(); 
      a.Add(1001); 
      a.Add(1001); 
      a.Add(1001); 
      a.Add(1001); 
      a.Add(2003); 
      a.Add(2003); 
      a.Add(2003); 

我需要做一個LINQ「去哪兒」這個名單,只在類型整數的回報(或限制)2。 所以結果應該是:

1001 
1001 
2003 
2003 

注:響應時間是在返回結果的主要因素。

回答

7

項目分組可以通過值,然後選擇從每個組前兩個項目:

var result = a.GroupBy(i => i).SelectMany(g => g.Take(2)); 

或查詢語法(以下美麗在這種情況下):

var result = from i in a 
      group i by i into g 
      from i in g.Take(2) 
      select i; 

因此分組將分組所有項目,只有結果將被返回,您可以編寫自定義擴展方法,它不會包含所有組項​​目(使用較少的內存)並以流方式返回項目,因爲它們來自於RCE序列:

public static IEnumerable<T> LimitElementOccurences<T>(
    this IEnumerable<T> source, int n) 
{ 
    return source.GoodMethodName(n, t => t); 
} 

public static IEnumerable<T> LimitElementOccurences<T, TKey>(
    this IEnumerable<T> source, int n, Func<T, TKey> keySelector) 
{ 
    var stats = new Dictionary<TKey, int>(); 

    foreach (var item in source) 
    { 
     var key = keySelector(item); 
     int returnedItemsCount; 
     if (!stats.TryGetValue(key, out returnedItemsCount)) 
     { 
      yield return item; 
      stats.Add(key, 1); 
      continue; 
     } 

     if (returnedItemsCount >= n) 
      continue; 

     yield return item; 
     stats[key] = returnedItemsCount + 1; 
    } 
} 

用法是(很抱歉,無法想象的好方法名)

var result = a.LimitElementOccurences(2); 
+0

我建議a.LimitElementOccurences(),就像一個名字稍微好一點? –

+1

偉大的擴展!我將不得不嘗試這個(明智的表現),只有這樣我才能夠標記這個答案! –

+0

如果我有一個類而不是整數來查看讓我們說列表,並且要查看的屬性是整數ID,那麼如何修改此擴展? –