繁体   English   中英

c# select 实例来自基于属性的类列表

[英]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)

LINQ

var best = data
    .GroupBy(x => x.Position)
    .Select(x => x.Aggregate(
        (result, item) => item.Quality > result.Quality ? item : result)
    );
  • 假设dataItem的集合
  • 确保using System.Linq;
  • bestIEnumerable ,如果您希望使用ToList()ToArray() ,您可以将其转换为列表或数组

根据讨论进行编辑:如果您的dataConsolidatedItems的实例,即嵌套集合,则需要先使用SelectMany将其展平:

var best = data
    .SelectMany(x => x)
    .GroupBy(x => x.Position)
    .Select(x => x.Aggregate(
        (result, item) => item.Quality > result.Quality ? item : result)
    );

细节

  1. data包含您的条目
  2. GroupBy创建一个集合,其中key是您选择用于分组的属性或计算值。 您当然可以遍历其所有项目,这些项目将在接下来的步骤中派上用场。
  3. Select将为每个组计算一个新实体——质量最好的那个。
  4. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM