使用LINQ计算两个列表中存在的组合数

时间:2010-06-17 21:23:55

标签: .net vb.net linq linq-to-objects

我正在尝试创建一个LINQ查询(或多个查询),用于计算一个列表中存在于不同列表中的项目组合的出现总数。例如,请使用以下列表:

CartItems                  DiscountItems
=========                  =============
AAA                        AAA
AAA                        BBB
AAA
BBB
BBB
CCC
CCC
DDD

查询操作的结果应为2,因为我可以在AAA的内容中找到BBBDiscountItems(来自CartItems)的两种组合。

我在处理查询时的想法是将列表加在一起以缩短CartItems以仅包含来自DiscountItems的项目。解决方案是在结果查询中找到发生次数最少的CartItem,从而指示CartItems中存在多少项组合。

CartItems仅过滤到DiscountItems中的项目时,可以直观地显示如下:

CartItems that get a discount
=============================
AAA    BBB    <=   This combination is eligible for a discount
AAA    BBB    <=   This combination is eligible for a discount
AAA           <=   Not eligible

因此,因为购物车中有2种折扣组合,结果为2。

如何做到这一点?


这是我已经拥有的查询,但它不起作用。 query导致包含100个项目的枚举,远远超出我的预期。

    Dim query = From cartItem In Cart.CartItems
                Group Join discountItem
                    In DiscountGroup.DiscountItems
                    On cartItem.SKU Equals discountItem.SKU
                    Into Group
                Select SKU = cartItem.SKU, CartItems = Group

    Return query.Min(Function(x) x.CartItems.Sum(Function(y) y.Quantity))

2 个答案:

答案 0 :(得分:3)

我认为你想要的是根据你的描述设置intersection的大小。

return Cart.CartItems.Intersect( DiscountGroup.DiscountItems ).Count()

这假设这些物品实际上是相同的(并且它们具有可比性)。如果没有,那么您需要选择用于比较它们的键并在键上进行交叉。

 return Cart.CartItems.Select( Function(c) c.SKU )
                      .Intersect( DiscountGroup.DiscountItems
                                               .Select( Function(d) d.SKU  )
                      .Count()

答案 1 :(得分:2)

如果我理解你的问题你想要这个:

int count = DiscountItems.Min(x => CartItems.Count(item => item == x));

结果:

2

这假设DiscountItems不能包含重复项。如果可以,并且您希望重复表示该项目必须在购物车中出现两次以计为一个折扣,那么请使用此代码:

int count = DiscountItems
    .GroupBy(d => d)
    .Min(x => CartItems.Count(item => item == x.Key) / x.Count());

我刚刚注意到你想在VB.NET中找到答案。我想你可以更容易地将它翻译成VB.NET,因为我的VB.NET不是那么好,但如果没有,那么留下一条消息,我将尝试通过.NET Reflector运行它,看看它是否可以将其自动翻译为可读的内容。