C# LINQ-仅列出最低价格

C# LINQ-仅列出最低价格,c#,linq,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 =>

考虑以下代码:

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\u number over
做了类似的工作。就个人而言,除非我完全写错了,否则我看不出上面的代码到底实现了什么


有什么建议吗?

您必须按
itemTypeId
分组,然后按
成本:

var o = items
    .GroupBy(x => x.itemTypeId)
    .Select(g => g.OrderBy(x => x.cost).First())
    .OrderBy(x => x.cost);

按项目类型分组,这将为您提供一个
i分组
,从中您可以获得一个键和一个分组项目的
i可数
。然后,您可以使用
i分组
上的
Min
(即
x
)将其投影(
Select
)为匿名类型,以获得每组的最低成本:

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

试图学习linq的人,尤其是聚合函数,从解释中受益匪浅。@Adamhuldsworth,我正要添加一些解释,这时我意识到我可能缺少一些
OrderBy
。谢谢,没问题。从技术上讲,订单将给出所需的输出,假设订单类型为项目类型(所需的输出在所需的订单上是不明确的,因为它也是以最低成本优先订购的),但我认为主要的混乱来源是分组,您的答案解决了这一问题。300来自哪里?不应该是150吗?在我的真实代码中,我有一个.SelectMany,它从其他表中提取数据。我有点不知道如何将此与上面的解决方案结合起来。我编辑了我的问题以显示。对不起,我在碰运气@舒舒服服地纳姆:也许你想问另一个问题。如果没有样本数据或表之间的关系,很难理解它。如果不是LINQ-To-Objects,您还应该提到LINQ提供者。足够公平-就可以了。再次感谢