我需要从道路收集中选择不同的高速公路。
我想我可以使用LINQ。
我有(存根代码)
Dim roads As List(Of Roads) = myRegion.Roads
Dim highways As New List(Of Highway)
For Each road In roads
If road.RoadType = RoadType.Highway Then
highways.Add(DirectCast(road, Highway))
End If
Next ic
' Now I think sorting them by .Id and then remove duplicates '
Dim myComparer As New HighwayByIdComparer
highways.Sort(myComparer)
也接受C#变体;)
答案 0 :(得分:4)
C#:
return myRegion.Roads
.Where(x => x.RoadType == RoadType.Highway)
.DistinctBy(x => x.Id);
(其中 DistinctBy 是Jon Skeet优秀的MoreLINQ项目中定义的扩展方法)
答案 1 :(得分:1)
编辑:我没有得到原始要求,将OrderBy更改为GroupBy / Select First。如果覆盖Equals方法来比较ID
,也可以简单地使用Distinct
var highways = roads.OfType<Highway>()
.GroupBy(x => x.Id)
.Select(x => x.First())
.ToList()
或在VB.Net中:
Dim highways = roads.OfType(Of Highway)().
GroupBy(Function(road) road.Id).
Select(Function(x) x.First()).
ToList()
答案 2 :(得分:1)
'道路模型
Public Class Road
Public Property Id As Integer
Public Property Name As String
Public Property RoadType As RoadType
End Class
'公路模型
Public Class Highway
Public Property Id As Integer
Public Property Name As String
End Class
'RoadType Enum
Public Enum RoadType
Residential
Highway
OffRoad
End Enum
'公路比较器(用于distinct子句)
Public Class HigwayNameComparer
Implements IEqualityComparer(Of Highway)
Public Function Equals(ByVal x As Highway, ByVal y As Highway) As Boolean Implements IEqualityComparer(Of Highway).Equals
Return x.Name = y.Name
End Function
Public Function GetHashCode(ByVal obj As Highway) As Integer Implements IEqualityComparer(Of Highway).GetHashCode
Return obj.Name.GetHashCode()
End Function
End Class
'控制台应用
Sub Main()
Dim roads As New List(Of Road)
roads.Add(New Road() With {.Id = 1, .Name = "Barclays Road", .RoadType = RoadType.Residential})
roads.Add(New Road() With {.Id = 2, .Name = "Effie Road", .RoadType = RoadType.Residential})
roads.Add(New Road() With {.Id = 3, .Name = "Out Road", .RoadType = RoadType.OffRoad})
roads.Add(New Road() With {.Id = 4, .Name = "M4", .RoadType = RoadType.Highway})
roads.Add(New Road() With {.Id = 5, .Name = "M4", .RoadType = RoadType.Highway})
Dim results = (From road In roads Where road.RoadType = RoadType.Highway
Select New Highway With {.Id = road.Id, .Name = road.Name}).Distinct(New HigwayNameComparer())
For Each highway As Highway In results
Console.WriteLine("{0}", highway.Name)
Next
Console.ReadLine()
End Sub
---输出:M4
答案 3 :(得分:0)
首先,您可以查看此博文:http://blogs.msdn.com/b/csharpfaq/archive/2009/03/25/how-to-use-linq-methods-to-compare-objects-of-custom-types.aspx。这表示您需要创建EqualityComparer<T>
,而不是简单地将其传递给Distinct
运营商。
roads.Where(r => r.RoadType == RoadType.Highway).Distinct(myComparer);
假设myComparer实际上正确实现了EqualityComaprer<T>
。
答案 4 :(得分:0)
您可以使用Road
的自定义相等比较器来使用Distinct()
:
public class RoadComparer : IEqualityComparer<Road>
{
public bool Equals(Road x, Road y)
{
return x.Id == y.Id;
}
public int GetHashCode(Road obj)
{
return obj.Id.GetHashCode();
}
}
var results = myRegion.Roads
.OfType<Highway>()
.Distinct(new RoadComparer())
.OrderBy( road => road.Id)
.ToList();