Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations John Tel on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Sort array of structure

Status
Not open for further replies.

virtuoso13

Technical User
Apr 11, 2007
4
SG
Hi all,

I have a problem in sorting array of structure. I found out a thread here talking about the same thing and it had been closed long time ago. I applied the codes and it does not seem to work.

Here's my code:
-- 1. I created an Icomparer class:

Public Class B2BLineComparer
Implements IComparer

Private mSortProperty As String
Private mSortOrder As SortOrder

Public Sub New(ByVal SortProperty As String, ByVal SortOrder As SortOrder)
Me.mSortProperty = SortProperty
Me.mSortOrder = SortOrder
End Sub

'Compare the two B2BLines.
Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
Dim ClientX As AC_SO.B2BLines = DirectCast(x, AC_SO.B2BLines)
Dim ClientY As AC_SO.B2BLines = DirectCast(y, AC_SO.B2BLines)
Dim strTempX As String
Dim strTempY As String
Dim intComparison As Integer

'CHECK WHICH PROPERTY WE ARE SORTING ON
If mSortProperty = "CustomerCode" Then
strTempX = ClientX.LnCardCode
strTempY = ClientY.LnCardCode
If mSortOrder = SortOrder.Ascending Then
intComparison = String.Compare(strTempX, strTempY)
Else
intComparison = String.Compare(strTempY, strTempX)
End If
ElseIf mSortProperty = "WarehouseCode" Then
strTempX = ClientX.LnWhseCode
strTempY = ClientY.LnWhseCode
If mSortOrder = SortOrder.Ascending Then
intComparison = String.Compare(strTempX, strTempY)
Else
intComparison = String.Compare(strTempY, strTempX)
End If
End If
'RETURN THE RESULT OF THE COMPARISON
Return intComparison
End Function
End Class


-- 2. I have defined a structure in another class AC_SO:

Public Structure B2BLines
Public LnCardCode As String
Public LnWhseCode As String
Public LnItemCode As String
Public LnCurrency As String
Public LnQuantity As Double
Public LnNetPrice As Double
Public LnDiscount As Double
End Structure

-- 3. I declare array of structure:
Private B2BLine(100) As B2BLines

-- 4. I filled data into the array.

-- 5. I'm sorting it:

'DECLARE COMPARER CLASS
Dim myComparer As New B2BLineComparer("Customer", SortOrder.Ascending)

'SORT THE ARRAYLIST AND PASS IN YOUR COMPARER OBJECT
Array.Sort(B2BLine, myComparer)

The problem is i do not understand how does the comparer work and in my case, it's not working properly. Is it something wrong with the codes? Or it's because im using Visual Studio 2003 in which i cannot directly use:
B2BLine.Sort(myComparer)
to sort the array of structure?

Please advise.

Thanks for your attention.

cheers,
erwine
 
I can see one thing wrong with it

Dim myComparer As New B2BLineComparer("Customer", SortOrder.Ascending)

should be

Dim myComparer As New B2BLineComparer("CustomerCode", SortOrder.Ascending)

But if that doesn't work I would need some test data perhaps even a unit test(if you have that).





Christiaan Baes
Belgium

"My old site" - Me
 
Hi chrissie,

That is syntax error. I had changed that as i also thought it was the cause. It seems like the array is somehow set to nothing because i tried to print out some values from the array of structure and it's blank.

If you need test data, perhaps i can provide SQL statement for the data and codes to populate the array. However, it's unlikely for you to have the solution files because the code is integrated to an application. so it's using its own object and cant run directly from .net.

I'm not familiar with IComparer and it's pretty confusing when i think about how .net uses the comparer class by calling Sort method and assign the comparer as a parameter.

I will write some codes for you to test and provide the data and get back to you.

Thanks anyway for the reply.

Cheers,
erwine
 
By test data I mean this

Code:
Private B2BLine(100) As B2BLines
B2BLine(0) = new B2BLines()
B2BLine(0). LnCardCode = "1"
B2BLine(1) = new B2BLines()
B2BLine(1). LnCardCode = "5"
B2BLine(2) = new B2BLines()
B2BLine(2). LnCardCode = "4"
B2BLine(3) = new B2BLines()
B2BLine(3). LnCardCode = "3"
B2BLine(4) = new B2BLines()
B2BLine(4). LnCardCode = "2"


Christiaan Baes
Belgium

"My old site" - Me
 
Well this works for me.


Code:
Dim B2BLine(4) As B2BLines

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        B2BLine(0) = New B2BLines()
        B2BLine(0).LnCardCode = "1"
        B2BLine(1) = New B2BLines()
        B2BLine(1).LnCardCode = "5"
        B2BLine(2) = New B2BLines()
        B2BLine(2).LnCardCode = "4"
        B2BLine(3) = New B2BLines()
        B2BLine(3).LnCardCode = "3"
        B2BLine(4) = New B2BLines()
        B2BLine(4).LnCardCode = "2"

        'DECLARE COMPARER CLASS
        Dim myComparer As New B2BLineComparer("CustomerCode", SortOrder.Ascending)
        filltext("before")
        'SORT THE ARRAYLIST AND PASS IN YOUR COMPARER OBJECT
        Array.Sort(B2BLine, myComparer)
        filltext("after")
    End Sub

    Private Sub filltext(ByVal s As String)
        Me.TextBox1.Text &= s & ControlChars.CrLf
        For Each b As B2BLines In B2BLine
            Me.TextBox1.Text &= b.LnCardCode & ControlChars.CrLf
        Next
    End Sub


End Class

Public Class B2BLineComparer
    Implements IComparer

    Private mSortProperty As String
    Private mSortOrder As SortOrder

    Public Sub New(ByVal SortProperty As String, ByVal SortOrder As SortOrder)
        Me.mSortProperty = SortProperty
        Me.mSortOrder = SortOrder
    End Sub

    'Compare the two B2BLines.
    Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
        Dim ClientX As B2BLines = DirectCast(x, B2BLines)
        Dim ClientY As B2BLines = DirectCast(y, B2BLines)
        Dim strTempX As String
        Dim strTempY As String
        Dim intComparison As Integer

        'CHECK WHICH PROPERTY WE ARE SORTING ON
        If mSortProperty = "CustomerCode" Then
            strTempX = ClientX.LnCardCode
            strTempY = ClientY.LnCardCode
            If mSortOrder = SortOrder.Ascending Then
                intComparison = String.Compare(strTempX, strTempY)
            Else
                intComparison = String.Compare(strTempY, strTempX)
            End If
        ElseIf mSortProperty = "WarehouseCode" Then
            strTempX = ClientX.LnWhseCode
            strTempY = ClientY.LnWhseCode
            If mSortOrder = SortOrder.Ascending Then
                intComparison = String.Compare(strTempX, strTempY)
            Else
                intComparison = String.Compare(strTempY, strTempX)
            End If
        End If
        'RETURN THE RESULT OF THE COMPARISON
        Return intComparison
    End Function
End Class


Public Structure B2BLines
    Public LnCardCode As String
    Public LnWhseCode As String
    Public LnItemCode As String
    Public LnCurrency As String
    Public LnQuantity As Double
    Public LnNetPrice As Double
    Public LnDiscount As Double
End Structure

Christiaan Baes
Belgium

"My old site" - Me
 
Hi Chrissie,

It worked now. It was my mistake as i declared the array with huge size and forgot to resize it.
Another issue is that I now need to sort it based on two elements (or fields).

it's like sorting using SQL statement (ORDER BY CustomerCode, WarehouseCode).

Is it possible to amend function Compare to accomodate this?

Thanks again for helping.

cheers,
erwine
 
Hi chrissie,

Got it. what do you think?
(note: always use ascending)

Public Class B2BLineComparer
Implements IComparer

Private sortElement

Public Sub New(ByVal sCategory As String)
Me.sortElement = sCategory
End Sub

Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
Dim ClientX As AC_SO.B2BLines = DirectCast(x, AC_SO.B2BLines)
Dim ClientY As AC_SO.B2BLines = DirectCast(y, AC_SO.B2BLines)
Dim strCardX, strCardY As String
Dim strWhseX, strWhseY As String
Dim intComparison As Integer

strCardX = ClientX.LnCardCode
strCardY = ClientY.LnCardCode
strWhseX = ClientX.LnWhseCode
strWhseY = ClientY.LnWhseCode

If sortElement = "cWhse" Then
Return String.Compare(strWhseX, strWhseY)
Else
intComparison = String.Compare(strCardX, strCardY)
If intComparison = 0 Then
Return String.Compare(strWhseX, strWhseY)
Else
Return intComparison
End If
End If

End Function
End Class

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top