[英]c# select instance from a list of classes based on property
鉴于以下 class 结构需要根据自定义属性值提取各种成员:
class Item{
public Item(int position, Image image)
{
Position = position;
Image = image;
}
public int Position { get; set; }
public Image Image { get; set; }
public int Quality { get; set; }
}
class Items : List<Item> {}
class ConsolidatedItems : List<Items> {}
如何获得基于由Position加入的质量的“最佳”项目列表(换句话说,Position 相同的组项目):
输入
Items1:
Item1: 1, ImageBinary, 100
Item2: 2, ImageBinary, 98
Item3: 3, ImageBinary, 45
Item4: 4, ImageBinary, 66
Items2:
Item1: 1, ImageBinary, 76
Item2: 2, ImageBinary, 80
Item4: 4, ImageBinary, 33
Items3:
Item1: 2, ImageBinary, 76
Item2: 3, ImageBinary, 80
Item4: 4, ImageBinary, 90
Output
BestItems:
Item1: 1, ImageBinary, 100 (from Items1)
Item2: 2, ImageBinary, 98 (from Items1)
Item3: 3, ImageBinary, 80 (from Items3)
Item4: 4, ImageBinary, 90 (from Items4)
var best = data
.GroupBy(x => x.Position)
.Select(x => x.Aggregate(
(result, item) => item.Quality > result.Quality ? item : result)
);
data
是Item
的集合using System.Linq;
best
是IEnumerable
,如果您希望使用ToList()
或ToArray()
,您可以将其转换为列表或数组根据讨论进行编辑:如果您的data
是ConsolidatedItems
的实例,即嵌套集合,则需要先使用SelectMany
将其展平:
var best = data
.SelectMany(x => x)
.GroupBy(x => x.Position)
.Select(x => x.Aggregate(
(result, item) => item.Quality > result.Quality ? item : result)
);
data
包含您的条目GroupBy
创建一个集合,其中key
是您选择用于分组的属性或计算值。 您当然可以遍历其所有项目,这些项目将在接下来的步骤中派上用场。Select
将为每个组计算一个新实体——质量最好的那个。Aggregate
可能是这里最难的 function。 它遍历组的成员并保留一个元素作为结果。 结果用第一个元素初始化。 然后Aggregate
继续遍历整个集合,并将每个项目与当前的最佳结果进行比较。 最后,它返回具有最佳元素的结果。请注意,您的集合类设计得不好。 看看这里为什么不继承表单 List 。
假设Position
已经填写,那么您可以使用 SelectMany 来展平您的 ConsolidatedItems,按 position 对它们进行分组,按 position 对组进行排序,然后从每个组中选择质量最好的组:
var bestItems = data
.SelectMany(x => x)
.GroupBy(x => x.Position)
.OrderBy(x => x.Key)
.Select(x => x.OrderByDescending(i=>i.Quality).First());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.