2011-03-02 24 views
3

我想排序類的列表,我需要的類與子類不是沒有第一個在列表中。我認爲以下將起作用,但它沒有。排序列表在哪裏對象不是Nothing

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

我知道這是最好(不在於它的工作原理),一個黑客,但我認爲它會移動類了其中子不等於什麼順序?

回答

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 

這也可以表示爲一個聲明拉姆達但他們只在Visual Studio 2010支持我選擇了寫一個全功能排序。

+0

啊好的謝謝你,這已經爲我清理了很多。希望使用lambda表達式,但正如我使用2008年,它不可能。將看看聲明lambda的未來,他們聽起來很有趣... – baileyswalk 2011-03-03 09:57:28

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)運行。

+0

謝謝,我明白你對比較函數的看法。不確定如何使用分區功能,稍後會仔細研究。 – baileyswalk 2011-03-03 10:10:25

+1

@baileyswalk分區函數採用一個布爾謂詞,它只返回當前對象是否爲'null'。分區的算法就是從數據兩端對數組進行線性傳遞,根據謂詞交換元素。由於它也用於快速排序,因此維基百科的文章有一個帶有僞代碼的部分:http://en.wikipedia.org/wiki/Quicksort#Complex_version(但這不是使用任意謂詞,而是與樞)。 – 2011-03-03 10:20:06

0

如果所有你想要的都是最後的'Nothing'值(在這種情況下性能不是一個大問題),你可以在通用列表上使用默認的.Sort()。這會給你前面的'Nothing'值。然後你打電話回去。

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() 
+0

性能不是一個巨大的問題,我會使用它,但需要在子類上進行排序。列表類類型始終有一個值。 – baileyswalk 2011-03-03 09:51:57