我有一个我的对象列表:
class MyObj
{
public String Title { get; set; }
public Decimal Price { get; set; }
public String OtherData { get; set; }
}
var list = new List<MyObj> {
new MyObj { Title = "AAA", Price = 20, OtherData = "Z1" },
new MyObj { Title = "BBB", Price = 20, OtherData = "Z2" },
new MyObj { Title = "AAA", Price = 30, OtherData = "Z5" },
new MyObj { Title = "BBB", Price = 10, OtherData = "Z10" },
new MyObj { Title = "CCC", Price = 99, OtherData = "ZZ" }
};
获取具有唯一标题和MAX(价格)的列表的最佳方法是什么。 结果列表必须是:
var ret = new List<MyObj> {
new MyObj { Title = "BBB", Price = 20, OtherData = "Z2" },
new MyObj { Title = "AAA", Price = 30, OtherData = "Z5" },
new MyObj { Title = "CCC", Price = 99, OtherData = "ZZ" }
};
答案 0 :(得分:16)
嗯,你可以这样做:
var query = list.GroupBy(x => x.Title)
.Select(group =>
{
decimal maxPrice = group.Max(x => x.Price);
return group.Where(x => x.Price == maxPrice)
.First();
};
如果你需要LINQ to SQL(你不能使用语句lambdas),你可以使用:
var query = list.GroupBy(x => x.Title)
.Select(group => group.Where(x => x.Price == group.Max(y => y.Price))
.First());
请注意,在LINQ to Objects中效率低于Where
的每次迭代时,它会重新计算最高价格。
如果您希望能够返回多个具有给定名称的项目(如果它们具有相同的价格),请调整.First()
部分。
在LINQ to Objects中你也可以使用MoreLINQ的MaxBy
方法:
var query = list.GroupBy(x => x.Title)
.Select(group => group.MaxBy(x => x.Price));
答案 1 :(得分:2)
var ret = list.GroupBy(x => x.Title)
.Select(g => g.Aggregate((a, x) => (x.Price > a.Price) ? x : a));
(如果您需要结果为List<T>
而非IEnumerable<T>
序列,则只需将ToList
电话标记到最后。)
答案 2 :(得分:1)
var ret = list.OrderByDescending(x => x.Price).GroupBy(x => x.Title).Select(@group => @group.ElementAt(0)).ToList();
这应该这样做。
答案 3 :(得分:0)
想提一下
var query = list.GroupBy(x => x.Title)
.Select(group => group.Where(x => x.Price == group.Max(y => y.Price))
.First());
应该是
var query = list.GroupBy(x => x.Title)
.First(group => group.Where(x => x.Price == group.Max(y => y.Price)));
我喜欢Richard解决最大n组/ 问题。
var query = list
.OrderByDescending(o => o.Price) //set ordering
.GroupBy(o => o.Title) //set group by
.Select(o => o.First()); //take the max element
但是需要稍加修改
var query = list
.OrderByDescending(o => o.Price) //set ordering
.GroupBy(o => o.Title) //set group by
.Select(o => o.Where(k => k.Price == o.First().Price)) //take max elements