1

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

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

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

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

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

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

有什么想法吗?谢谢

4

3 回答 3

2

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此外,您可以通过使原始类型使用 a而不是字符串来简化一切。

于 2012-07-09T22:43:53.403 回答
1

用漂亮的 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。

于 2012-07-09T22:43:42.663 回答
1

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

var namesWithHighestVersion = 
    appDetailList
        .GroupBy(a => a.Name)
        .Select(g => g.OrderByDescending(a => a.Version).First())
        .ToList();
于 2012-07-09T23:16:13.997 回答