LINQ:GroupBy,每个组中的最大数量 [英] LINQ: GroupBy with maximum count in each group

查看:79
本文介绍了LINQ:GroupBy,每个组中的最大数量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个重复的号码列表:

I have a list of duplicate numbers:

Enumerable.Range(1,3).Select(o => Enumerable.Repeat(o, 3)).SelectMany(o => o)
// {1,1,1,2,2,2,3,3,3}

我将它们分组并得到出现的数量:

I group them and get quantity of occurance:

Enumerable.Range(1,3).Select(o => Enumerable.Repeat(o, 3)).SelectMany(o => o)
    .GroupBy(o => o).Select(o => new { Qty = o.Count(), Num = o.Key })

Qty   Num
3     1
3     2
3     3

我真正需要的是将每组的数量限制为一定数量.如果限制为2,则上述分组的结果将是:

What I really need is to limit the quantity per group to some number. If the limit is 2 the result for the above grouping would be:

Qty   Num
2     1
1     1
2     2
1     2
2     3
1     3

因此,如果Qty = 10且限制为4,则结果为3行(4、4、2).每个数字的数量不等于示例.整个列表中指定的数量限制"相同(根据数量而定).

So, if Qty = 10 and limit is 4, the result is 3 rows (4, 4, 2). The Qty of each number is not equal like in example. The specified Qty limit is the same for whole list (doesn't differ based on number).

谢谢

推荐答案

有一个

There was a similar question that came up recently asking how to do this in SQL - there's no really elegant solution and unless this is Linq to SQL or Entity Framework (i.e. being translated into a SQL query), I'd really suggest that you not try to solve this problem with Linq and instead write an iterative solution; it's going to be a great deal more efficient and easier to maintain.

也就是说,如果您绝对必须使用基于集合的("Linq")方法,则可以采用以下方法:

That said, if you absolutely must use a set-based ("Linq") method, this is one way you could do it:

var grouped =
    from n in nums
    group n by n into g
    select new { Num = g.Key, Qty = g.Count() };

int maxPerGroup = 2;
var portioned =
    from x in grouped
    from i in Enumerable.Range(1, grouped.Max(g => g.Qty))
    where (x.Qty % maxPerGroup) == (i % maxPerGroup)
    let tempQty = (x.Qty / maxPerGroup) == (i / maxPerGroup) ? 
        (x.Qty % maxPerGroup) : maxPerGroup
    select new
    {
        Num = x.Num,
        Qty = (tempQty > 0) ? tempQty : maxPerGroup
    };

与更简单,更快速的迭代版本进行比较:

Compare with the simpler and faster iterative version:

foreach (var g in grouped)
{
    int remaining = g.Qty;
    while (remaining > 0)
    {
        int allotted = Math.Min(remaining, maxPerGroup);
        yield return new MyGroup(g.Num, allotted);
        remaining -= allotted;
    }
}

这篇关于LINQ:GroupBy,每个组中的最大数量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆