这是对我不久前发布的一个问题的跟进。我得到了一个答案,但我意识到我已经简化了我的示例类,以至于我失去了最初的意图。在接受了原来问题的答案后,我认为最好再开始另一个问题。
这是我的新课:
public class Art
{
public string Type { get; set; }
public string Name { get; set; }
public int Price { get; set; }
}...and,下面是列表创建:
public static void Example0000()
{
List<Art> art = new List<Art>();
art.Add(new Art() { Price = 45, Type = "painting", Name = "Still Life in Maryland" });
art.Add(new Art() { Price = 123, Type = "sculpture", Name = "Dying Sheep" });
art.Add(new Art() { Price = 12, Type = "icon", Name = "Perplexed Smiley" });
art.Add(new Art() { Price = 460, Type = "sculpture", Name = "Waves on Sand" });
art.Add(new Art() { Price = 2030, Type = "painting", Name = "Robert in the Morning" });
art.Add(new Art() { Price = 10, Type = "icon", Name = "Smiley Picking Nose" });
art.Add(new Art() { Price = 700, Type = "painting", Name = "Birds in Autumn" });
art.Add(new Art() { Price = 1400, Type = "sculpture", Name = "Holding Hands" });
art.Add(new Art() { Price = 46, Type = "painting", Name = "Reeling Him In" });
art.Add(new Art() { Price = 12000, Type = "sculpture", Name = "Old Dog" });
art.Add(new Art() { Price = 6, Type = "icon", Name = "Hiding Smiley" });
art.Add(new Art() { Price = 810, Type = "sculpture", Name = "Rhinestone Cowgirl" });
art.Add(new Art() { Price = 250, Type = "painting", Name = "Upstairs, Downstairs" });
art.Add(new Art() { Price = 3, Type = "icon", Name = "Dopey Smiley" });
art.Add(new Art() { Price = 1000, Type = "painting", Name = "Young Love" });
art.Add(new Art() { Price = 260, Type = "sculpture", Name = "Taking a Spill" });
}我想要的是一个对象集合,每个类型都有一个对象,它们有三个属性: ArtType、ArtName和MostExpensivePrice。对于每种类型,我想要的名称和价格的最高价格的项目的类型。
所以我的清单应该是:
painting______Robert_in_the_Morning______2030
sculpture_____Old Dog__________________12000
icon_________Perplexed Smiley______________12
那么LINQ会是什么样的呢?我开始的示例如下所示:
var categories4 =
from a in art
group a by a.Type into g
let maxPrice = g.Max(p => p.Price)
select new { ArtType = g.Key, MostExpensive = g.Where(a => a.Price == maxPrice) };发布于 2014-10-15 00:46:42
请参见Enumerable.Aggregate()方法。
到目前为止,给出的另一个答案只是返回最高价格,这不是你在这里要求的。如果您像这样使用Enumerable.Aggregate():
MostExpensive = g.Aggregate((art1, art2) => (art1.Price > art2.Price) ? art1 : art2)然后,LINQ结果将包含Art实例,而不是int实例,因此您可以以最大值而不是仅显示价格来显示所有信息。
编辑:
如果上面的内容并不明显,那么完整的表达式可以是:
var artprices =
from a in art
group a by a.Type into g
let mostExpensive = g.Aggregate((art1, art2) => (art1.Price > art2.Price) ? art1 : art2)
select new { ArtType = g.Key, ArtName = mostExpensive.Name, MostExpensivePrice = mostExpensive.Price };你会得到一个结果,元素有你想要的三个值。
编辑2:
最后,作为新的网站,我不能添加评论到其他答案,但我会尽可能客观地指出,他们都有缺陷,以不同的方式。
一个答案是,对原始集合中的每个元素进行一次评估,然后对每个Type值(即每个组)进行一次评估。这是一个典型的O(N^2)场景,它将在非常小的数据集上执行得很好,但是对于任何非平凡的数据集合来说都是非常糟糕的。
另外两个答案建议对每一组中的元素进行排序。这样做更好,但仍然需要该排序的内存和性能开销。典型的排序是O(N log N),这比O(N^2)好得多,但仍然不如使用聚合()获得的线性O(N)好。同样,小数据集完全没有问题,但是与更有效的方法相比,一个非平凡的集合将导致显着的性能下降。
希望这能帮上忙!
发布于 2014-10-15 01:38:12
这个对你有用吗?
var query =
art
.OrderByDescending(x => x.Price)
.GroupBy(x => x.Type)
.Select(x => x.First());我得到了这个结果:

发布于 2014-10-15 01:02:54
好吧,你把第一部分说对了,你只是有点偏离了第二部分。您需要做的第一件事是了解GroupBy方法返回的内容。GroupBy本质上返回列表列表(数组数组或可枚举的可枚举列表)。
使用声明为您的类型是:
public class Art
{
public string Type { get; set; }
public string Name { get; set; }
public int Price { get; set; }
}根据这些数据:
List<Art> art = new List<Art>()
{
new Art() { Price = 45, Type = "painting", Name = "Still Life in Maryland" }),
new Art() { Price = 123, Type = "sculpture", Name = "Dying Sheep" }),
new Art() { Price = 12, Type = "icon", Name = "Perplexed Smiley" }),
new Art() { Price = 460, Type = "sculpture", Name = "Waves on Sand" });,
new Art() { Price = 2030, Type = "painting", Name = "Robert in the Morning" }),
new Art() { Price = 10, Type = "icon", Name = "Smiley Picking Nose" }),
new Art() { Price = 700, Type = "painting", Name = "Birds in Autumn" }),
new Art() { Price = 1400, Type = "sculpture", Name = "Holding Hands" }),
new Art() { Price = 46, Type = "painting", Name = "Reeling Him In" }),
new Art() { Price = 12000, Type = "sculpture", Name = "Old Dog" }),
new Art() { Price = 6, Type = "icon", Name = "Hiding Smiley" }),
new Art() { Price = 810, Type = "sculpture", Name = "Rhinestone Cowgirl" }),
new Art() { Price = 250, Type = "painting", Name = "Upstairs, Downstairs" }),
new Art() { Price = 3, Type = "icon", Name = "Dopey Smiley" }),
new Art() { Price = 1000, Type = "painting", Name = "Young Love" }),
new Art() { Price = 260, Type = "sculpture", Name = "Taking a Spill" })
}将艺术品列表分组,结果如下所示:
IEnumerable<IGrouping<string, Art>> groupedByType = art.GroupBy(a => a.Type);其中,每个IGrouping<string, Art>包含一个Art列表,其中列表中的每个部分都具有相同的Type。在第二步中,我们只需要从每一组中选择最高价格:
IEnumerable<Art> maxFromEachGroup = groupedByType
// Take a single piece of art from each group
.Select(group =>
// Get the maximum piece of art by ordering from largest to smallest
// and taking the first
group.OrderByDescending(a => a.Price).First()
);现在您有了一个Art列表,其中包含了每个组中最昂贵的部分。使用最大值需要注意的是,它返回最高价格的值,而不是以最大价格返回Art的部分。因此,LINQ表达式表单中的整个表达式是:
var maxFromEachGroup = from a in art
group a by a.Type into g
select (from a in g orderby a.Price descending select a).First();https://stackoverflow.com/questions/26372606
复制相似问题