排序列表,其中对象IsNot Nothing

时间:2011-03-02 17:39:02

标签: .net vb.net generics list lambda

我正在尝试对类列表进行排序,并且我需要具有子类的类,这些类在列表中并不是第一位的。我认为以下内容可行,但它没有。

ListOfClasses.Sort(Function(x, y) If(x.SubClass IsNot Nothing, 1, 0))

我知道这是一个充其量的黑客(不是它有效)但我认为它会将类移动到子类不等于什么的顺序?

3 个答案:

答案 0 :(得分:3)

如果x小于,等于或大于y,则比较器函数需要返回-1,0或1。在您的情况下(因为您希望在后面有Nothing个值):

Dim xNull = x Is Nothing
Dim yNull = y Is Nothing

If xNull = yNull Then Return 0 ' either both are Nothing, or neither is.
If xNull Then Return 1
Return -1

但请注意,在这里使用Sort是不必要的低效率。您需要的操作称为partition,并以O(n)运行。

答案 1 :(得分:2)

此处的问题是您的比较器代理未遵循列出here列出的正确比较规则。特别是它需要确保如果你说'x大于y',你也会说'y小于x'。在这里,你只是说'x大于y',但你实际上并没有说相反。

这是一个比较器函数,可以正确地对这些元素进行排序

Function Compare(ByVal x as TheType, ByVal y as TheType) As Integer
  If x.SubClass Is Nothing AndAlso y.SubClass Is Nothing Then
    Return 0
  Else If x.SubClass IsNot Nothing AndAlso y.SubClass IsNot Nothing Then
    Return 0
  Else If x.SubClass IsNot Nothing Tehn
    Return -1
  Else
    Return 1
  End If 
End Function

这也可以表示为语句lambda,但由于它们仅在Visual Studio 2010中受支持,因此我选择编写完整函数。

答案 2 :(得分:0)

如果您想要的只是最后的所有'Nothing'值(并且在这种情况下性能不是一个大问题),您可以在通用列表中使用默认的.Sort()。这将为您提供前面的“Nothing”值。然后你在列表上调用.Reverse。

Dim ListOfClasses As New List(Of Object)
ListOfClasses.Add(Nothing)
ListOfClasses.Add("Something 1")
ListOfClasses.Add(Nothing)
ListOfClasses.Add("Something 2")
ListOfClasses.Add(Nothing)
ListOfClasses.Add("Something 3")

ListOfClasses.Sort()
ListOfClasses.Reverse()