如何优雅地使用自定义比较器对VB.net中的对象进行排序?

时间:2016-03-20 09:57:55

标签: vb.net sorting

我想对一堆domainsdata对象进行排序。我想先根据countryCode排序,然后根据收入进行排序。

首先我创建了一个私有比较器。

Private Function CompareDomainCountry(ByVal x As domainsData, ByVal y As domainsData) As Integer
    If x.countryCode < y.countryCode Then
        Return -1
    ElseIf y.countryCode < x.countryCode Then
        Return 1
    ElseIf x.revenue < y.revenue Then
        Return 1
    ElseIf y.revenue < x.revenue Then
        Return -1
    Else
        Return 0
    End If
End Function

这有几个问题。

比较器返回1,-1,0。我认为应该有一个正常的枚举。

另外我认为我的比较器应该简单地调用标准的vb.net比较器。

之后,我如何排序(domainsdata)列表?

比较器?

2 个答案:

答案 0 :(得分:1)

首先,请注意您的收入比较代码不一致:较小的X应返回-1。你也不一定需要这种方法。这给出了相同的结果:

Dim sorted = DomainList.OrderBy(Function(x) x.CountryCode).
                         ThenBy(Function(y) y.Revenue).
                         ToList()

如果您想依赖标准的.NET方法,您的方法可以是类成员:

Public Class DomainComparer
    Implements IComparer(Of Domain)

    Public Function Compare(x As Domain, y As Domain) As Integer _ 
                                         Implements IComparer(Of Domain).Compare
        ' all your code
    End Function
End Class

然后使用它:

Dim dSorter = New DomainComparer
DomainList.Sort(dSorter)
' or simply:
DomainList.Sort(New DomainComparer)

Guffa先生的AddressOf方法更简单,更简洁;当有其他变量/属性(如SortOrder)时,我喜欢类方法。

结果是相同的两种方式(当收益结果发生变化时),除非排序成员是混合字母数字字符串(根据名称和比较似乎不是这种情况)。

如果您希望将您的方法与OrderBy()一起使用,我认为您无法使用 - 签名与Func(Of T)(TKey)不匹配。然而,返回是统一的,大多数Compare()方法都表示较大的值(DateTime表示较小/较早的日期;可能还有其他日期。)

答案 1 :(得分:1)

您可以使用CompareTo方法比较值。如果第一次比较为零,则进行另一次比较:

Private Function CompareDomainCountry(ByVal x As domainsData, ByVal y As domainsData) As Integer
  Dim result As Integer = x.countryCode.CompareTo(y.countryCode)
  If result = 0 Then
    result = x.revenue.CompareTo(y.revenue)
  End If
  Return result
End Function

要使用比较对列表进行排序,请在Sort方法调用中使用它:

myList.Sort(AddressOf CompareDomainCountry)