[英]get distinct item in List with highest value in property
I have an object AppDetail containing 2 string properties, a name, and a version string (eg "1.0.0") 我有一个对象AppDetail包含2个字符串属性,一个名称和一个版本字符串(例如“1.0.0”)
Given a List< AppDetail > that contains duplicates of the same name but different version strings, how do I create a List with unique names, and highest versions? 如果List <AppDetail>包含相同名称但不同版本字符串的重复项,如何创建具有唯一名称和最高版本的List?
eg from these 2 items in the initial list 例如,从初始列表中的这2个项目开始
"name", "1.0.1"
"name", "1.1.0"
I want the unique items list to contain only the second item, since it has the highest version. 我希望唯一项目列表仅包含第二个项目,因为它具有最高版本。
To compare versions I need to create an IComparer that creates Version objects and then to use the version.CompareTo(version) method. 要比较版本,我需要创建一个IComparer来创建Version对象,然后使用version.CompareTo(version)方法。 But thats not useful, since the List.Distinct overload only accepts IEqualityComparer, not IComparer.
但这没用 ,因为List.Distinct重载只接受IEqualityComparer,而不接受IComparer。
Any thoughts? 有什么想法吗? Thanks
谢谢
It makes sense that List.Distinct()
doesn't accept an IComparer
, since determining if two items are distinct does not require knowing if one item would precede another (or visa versa,) which is the purpose of the IComparer
interface. 有意义的是
List.Distinct()
不接受IComparer
,因为确定两个项是否是不同的并不需要知道一个项是否先于另一项(反之亦然),这是IComparer
接口的目的。 Rather, all that is needed is to know whether or not two items are equal , which is exactly why IEqualityComparer
exists. 相反,所需要的只是知道两个项是否相等 ,这正是
IEqualityComparer
存在的原因。
You don't need to implement either, though. 但是,您也不需要实现。 You can create a query that selects the appropriate items, by first grouping all the items by name, and then selecting only the highest version number from each group:
您可以创建一个选择相应项目的查询,首先按名称对所有项目进行分组,然后仅从每个组中选择最高版本号:
var namesWithHighestVersion =
appDetailList
.GroupBy(x => x.Name)
.Select(x => new AppDetail {
Name = x.Key,
Version = x.Max(x => new Version(x.Version)).ToString()
})
.ToList();
Note that this creates a new list, rather than updating the old list. 请注意,这会创建一个新列表,而不是更新旧列表。
Also, you could simplify everything somewhat by making the original type use a Version
, instead of a string. 此外,您可以通过使原始类型使用
Version
而不是字符串来简化一切。
simple query shown in pretty sql: 简单的查询显示在漂亮的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();
The grouping will naturally make the query distinct 分组自然会使查询区别开来
Sorry about earlier in using MaxBy, including the following project found here: "more linq" made me think of MaxBy instinctively. 很抱歉早些时候使用MaxBy,包括以下项目: “more linq”让我本能地想起MaxBy。
This solution is similar to dlev's answer, however, it will return the instance of the one with the highest version, instead of creating a new instance with the same values. 此解决方案类似于dlev的答案,但是,它将返回具有最高版本的实例,而不是创建具有相同值的新实例。
var namesWithHighestVersion =
appDetailList
.GroupBy(a => a.Name)
.Select(g => g.OrderByDescending(a => a.Version).First())
.ToList();
var latestVersion =(来自appDetailList中的a选择a.Version).Max();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.