【问题标题】:get distinct item in List with highest value in property获取列表中具有最高属性值的不同项目
【发布时间】:2012-07-09 22:33:48
【问题描述】:

我有一个对象 AppDetail,其中包含 2 个字符串属性、一个名称和一个版本字符串(例如“1.0.0”)

给定一个 List 包含相同名称但不同版本字符串的重复项,我如何创建一个具有唯一名称和最高版本的 List?

例如从初始列表中的这两个项目中

"name", "1.0.1"
"name", "1.1.0"

我希望唯一项列表仅包含第二项,因为它具有最高版本。

要比较版本,我需要创建一个创建 Version 对象的 IComparer,然后使用 version.CompareTo(version) 方法。但这没有用,因为List.Distinct overload 只接受 IEqualityComparer,而不接受 IComparer。

有什么想法吗?谢谢

【问题讨论】:

    标签: c# linq list iequalitycomparer


    【解决方案1】:

    List.Distinct() 不接受 IComparer 是有道理的,因为确定两个项目是否不同并不需要知道一个项目是否会在另一个之前(反之亦然)是IComparer 接口的用途。相反,只需要知道两个项目是否相等,这正是IEqualityComparer 存在的原因。

    不过,您也不需要实现。您可以创建一个选择适当项目的查询,首先按名称对所有项目进行分组,然后从每个组中仅选择最高版本号:

    var namesWithHighestVersion = 
        appDetailList
            .GroupBy(x => x.Name)
            .Select(x => new AppDetail { 
                             Name = x.Key,
                             Version = x.Max(x => new Version(x.Version)).ToString()
                            })
            .ToList();
    

    请注意,这会创建一个新列表,而不是更新旧列表。

    此外,您可以通过使原始类型使用Version 而不是字符串来简化一切。

    【讨论】:

      【解决方案2】:

      此解决方案类似于 dlev 的答案,但是,它将返回具有最高版本的实例,而不是创建具有相同值的新实例。

      var namesWithHighestVersion = 
          appDetailList
              .GroupBy(a => a.Name)
              .Select(g => g.OrderByDescending(a => a.Version).First())
              .ToList();
      

      【讨论】:

      • 这绝对是相似的,但在一个关键方面是错误的:使用 string 参数调用 OrderByDescending() 将按字典顺序对项目进行排序,这在处理版本号时可能是错误的(例如 2.2 > 2.10当两者都被视为字符串时。)
      【解决方案3】:

      用漂亮的 sql 显示的简单查询:

      var aDetail  =  from a in appdetail
                      group a by a.name into aGroup
                      orderby a.version descending
                      select new 
                          {name = aGroup.name, 
                           version = aGroup.Max(version)}.ToList();
      

      分组自然会使查询与众不同

      很抱歉之前使用 MaxBy,包括在此处找到的以下项目:"more linq" 让我本能地想到了 MaxBy。

      【讨论】:

        猜你喜欢
        • 2022-11-24
        • 1970-01-01
        • 1970-01-01
        • 2014-06-09
        • 2018-09-21
        • 2010-09-14
        • 1970-01-01
        • 2020-08-05
        • 1970-01-01
        相关资源
        最近更新 更多