LINQ - 仅列出最低价格

时间:2015-11-05 14:55:37

标签: c# linq

考虑以下代码:

var items = (new[] { 
    new {itemTypeId = 1 , cost=100 },
    new {itemTypeId = 2 , cost=200 },
    new {itemTypeId = 1 , cost=50 },
    new {itemTypeId = 3 , cost=150 },
    new {itemTypeId = 1 , cost=75 }
});

var o = items.OrderBy(x => x.cost)
    .ToList()
    .GroupBy(x => x.itemTypeId )
    .Select(g => new { g, count = g.Count() })
    .SelectMany(t => t.g.Select(b => b).Zip(Enumerable.Range(1, t.count), (j, i) => new { j.itemTypeId , j.cost }));

foreach (var i in o)
{
    Console.WriteLine("{0} {1} ", i.itemTypeId, i.cost);
}

输出:

1 | 50  
1 | 75  
1 | 100  
3 | 300  
2 | 200

我实际上想要输出:

1 | 50   
2 | 200
3 | 300

查询应仅返回价格最低的特定类型的产品。因此,在任何返回的数据中,每个项目类型应该只有一个,并按价格排序。

我认为Enumerable.Range(1, t.count)在TSQL中与Row_number over做了类似的工作。我个人无法看到上述代码究竟实现了什么,除非我写错了。

有什么建议吗?

2 个答案:

答案 0 :(得分:7)

按项目类型分组,为您提供IGrouping<T>,您可以从中获得密钥和IEnumerable<T>个分组项目。然后,您可以使用SelectMin IGrouping<T>x投影到匿名类型中,以获得每组最低的费用:

items
    .GroupBy(x => x.itemTypeId)
    .Select(x => new { ItemTypeId = x.Key, Cost = x.Min(z => z.cost) })
    .OrderBy(x => x.Cost)

答案 1 :(得分:6)

您必须按itemTypeId进行分组,然后按cost:

对该群组进行排序,以获取最低分数
var o = items
    .GroupBy(x => x.itemTypeId)
    .Select(g => g.OrderBy(x => x.cost).First())
    .OrderBy(x => x.cost);