Linq查询选择顶级记录

时间:2011-12-22 11:12:46

标签: c# linq

我有IEnumerable<MyData>,其中包含以下数据

Fruits | Name | Quantity | 
__________________________
 Mango | Jay  |    10    |
__________________________
 Apple | Jay  |    16    |
__________________________
 Grapes| Jay  |    12    |
__________________________
 Mango | Raj  |    11    |
__________________________
 Apple | Raj  |    20    |
__________________________
 Grapes| Raj  |    3     |
__________________________
 Mango | Vik  |    20    |
__________________________
 Apple | Vik  |    15    |
__________________________

我需要根据名称选择Linq前两个数量,如

Jay (10+16+12) = 38
Raj (11+20+3) = 34
Vik (20+15) = 35
Jay和Vik有两个数量之和,所以我需要这些记录

Fruits | Name | Quantity | 
__________________________
 Mango | Jay  |    10    |
__________________________
 Apple | Jay  |    16    |
__________________________
 Grapes| Jay  |    12    |
__________________________
 Mango | Vik  |    20    |
__________________________
 Apple | Vik  |    15    |
__________________________

4 个答案:

答案 0 :(得分:11)

听起来你可能想要这样的东西:

var query = from item in collection
            group item by item.Name into g
            orderby g.Sum(x => x.Quantity)  descending
            select g;
var topTwo = query.Take(2);

这将采用前两个,因此您将其用作:

foreach (var group in topTwo)
{
    Console.WriteLine("Name: {0}", group.Key);
    foreach (var item in group)
    {
        Console.WriteLine("  {0}: {1}", item.Fruits, item.Quantity);
    }
}

答案 1 :(得分:4)

这样的事情会起作用。

private static IEnumerable<MyData> GetTop2Names(IEnumerable<MyData> data)
{
    var top2 = data.GroupBy(d => d.Name)
                   .OrderByDescending(g => g.Sum(d => d.Quantity))
                   .Take(2)
                   .Select(g => g.Key);
    return data.Where(d => top2.Contains(d.Name));
}

一步一步

  1. 按名称分组(就像你要汇总的那样)
  2. 按数量总和排序
  3. 取前2名
  4. 从原始列表中选择与这些名称匹配的项目。

答案 2 :(得分:0)

尝试以下方法:

var topTwo = myData.GroupBy(d => d.Name).OrderByDescending(g => g.Sum(d => d.Quantity)).TakeWhile((data,index) => index < 2).SelectMany(g => g);

答案 3 :(得分:0)

应该是这样的:

IEnumerable<MyData> source = new List<MyData>();
var names = source
    .GroupBy(item => item.Name)
    .ToDictionary(item => item.Key, item => item.Sum(i => i.Quantity))
    .OrderByDescending(item => item.Value)
    .Select(item => item.Key)
    .Take(2);

var result = source.Where(item => names.Contains(item.Name));