在List中获取具有最高属性值的不同项

时间:2012-07-09 22:33:49

标签: c# linq list iequalitycomparer

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

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

e.g。来自初始列表中的这2项

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

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

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

有什么想法?感谢

4 个答案:

答案 0 :(得分: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而不是字符串来简化所有内容。

答案 1 :(得分: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。

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

var latestVersion =(来自appDetailList中的a选择a.Version).Max();