C# LINQ在结果中设置限制

C# LINQ在结果中设置限制,c#,linq,limit,C#,Linq,Limit,我有一个整数列表: 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); 注意:响应时间是返回结果的一个主要因素。

我有一个整数列表:

 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);

注意:响应时间是返回结果的一个主要因素。

根据项目值对项目进行分组,然后从每组中选择前两个项目:

var result = a.GroupBy(i => i).SelectMany(g => g.Take(2));
或查询语法(在本例中不太美观):


因此,分组将对所有项目进行分组,只有这样结果才会返回,您可以编写自定义扩展方法,该方法不会保存所有项目组(将使用更少的内存),并以流式方式返回来自源序列的项目:

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;
    }
}

我可以推荐a.LimitElementOccurences()作为一个稍微好一点的名字吗?很好的扩展!我将不得不尝试这一点(性能方面),只有这样我才能将其标记为已回答!如果我要查看的是类而不是整数,并且要查看的属性是整数ID,您将如何修改此扩展名?@MurtazaMandvi您不需要修改它:
List.LimitElementOccurences(2,sc=>sc.ID)
var result = from i in a
             group i by i into g
             from i in g.Take(2)
             select i;
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);