I'm having trouble implementing an IComparer method. Essentially, I want to compare the properties of two custom objects (the properties are of type integer).
dE is a Dictionary(Of String, customObj) prTabIndex is a property of customObj and is of type Integer (these hold true for all examples)
After some more searching I found this thread which suggested 3 things: a List approach, utilizing LINQ, and using some C# 3.0 features. However, being in vb, not sure what they best approach is.
I've tried three different ways:
...rolling my own IComparer implementation:
Public m As Sub(ByRef d As Dictionary(of String, customObj))
Dim sortedD As New SortedDictionary(Of String, customObj)(d, myCompare)
End Sub
Public Class myCompare
Implements IComparer
Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
If TryCast(x, customObj).prTabIndex < TryCast(y, customObj).prTabIndex Then
Return -1
Else
Return 1
End If
End Function
End Class
...Sorting a list (which, I think works - making this thread slightly academic).
Dim sortedL As List(Of KeyValuePair(Of String, customObj)) = dE.ToList
sortedL.Sort(Function(firstPair As KeyValuePair(Of String, customObj), nextPair As KeyValuePair(Of String, customObj)) firstPair.Value.prTabIndex.CompareTo(nextPair.Value.prTabIndex))
...or incorporating the lambda function directly in the conversion to the SortedDictionary:
Dim dESorted = From kvp As KeyValuePair(Of String, customObj) In dE.ToDictionary(Function(first As KeyValuePair(Of String, customObj), second As KeyValuePair(Of String, customObj)) first.Value.prTabIndex.CompareTo(nextPair.Value.prTabIndex))
Note that VS2008 has underlined 'dE.ToDictionary...' (to the end of the line) and giving me two messages depending on where I hover my mouse:
1) "Data type(s) of the type parameter(s) in extension method 'signature' As 'signature defined in 'System.Linq.Enumerable cannot be inferred from these arguments. Specifying the data types explicitly might correct this error. Seen while hovering over "ToDictionary".
2) Nested function does not have the same signature as delegate 'signature'. Seen while hovering over anything after "ToDictionary".
Admittedly, I'm new to lambda functions.
Q1) How far off am I in each of the implementations?
Q2) Which one is the computationally least expensive? Why?
Q3) Which one is the computationally most expensive? Why?
Warm Regards,
-sf
You can save your self casting if you implement the Generic IComparable(Of ...). I think you should also handle the possibility that the two objects are equal.
Public Class DemoClass
Implements IComparable(Of DemoClass)
Private mstrField1 As String
Public Property Field1() As String
Get
Return mstrField1
End Get
Set(ByVal value As String)
mstrField1 = value
End Set
End Property
Private mstrField2 As String
Public Property Field2() As String
Get
Return mstrField2
End Get
Set(ByVal value As String)
mstrField2 = value
End Set
End Property
Private mstrField3 As String
Public Property Field3() As String
Get
Return mstrField3
End Get
Set(ByVal value As String)
mstrField3 = value
End Set
End Property
''' <summary>
''' Default sort - 1 ASC, 2 ASC, 3 ASC
''' </summary>
''' <param name="other"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Function CompareTo(ByVal other As DemoClass) As Integer Implements System.IComparable(Of DemoClass).CompareTo
'-1 = less than other; 0 = same as other; +1 = greater than other'
Select Case Me.Field1
Case Is < other.Field1 : Return -1
Case Is > other.Field1 : Return 1
Case Else 'equal
Select Case Me.Field2
Case Is < other.Field2 : Return -1
Case Is > other.Field2 : Return 1
Case Else 'equal
Select Case Me.Field3
Case Is < other.Field3 : Return -1
Case Is > other.Field3 : Return 1
Case Else : Return 0 'equal
End Select
End Select
End Select
End Function
End Class