ArrayList Sort

TexasTee

New member
Joined
Aug 3, 2009
Messages
2
Programming Experience
Beginner
I am trying to sort an arraylist that contains the following values.

A - Value for A
1 - Value for 1
5 - Value for 5
3 - Value for 3
30 - Value for 30
50 - Valure for 50

When I use ArrayList.Sort() I am getting the following.

1 - Value for 1
3 - Value for 3
30 - value for 30
5 - value for 5
50 - value for 50
A - Value for A

What I want to see is:

1 - Value for 1
3 - Value for 3
5 - value for 5
30 - value for 30
50 - value for 50
A - Value for A

Please help if you can.
 
It looks like it is sorting based on the string datatype rather than the numeric datatype. You can write your own comparer class to help.

I'm not sure if this is correct so I'm sure you will have to fiddle with it a bit.
VB.NET:
 Public Class MyComparer
        Implements IComparer

        Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
            'Both Numbers
            If IsNumeric(x) And IsNumeric(y) Then
                Return CDbl(x).CompareTo(y)
            ElseIf IsNumeric(x) And Not IsNumeric(y) Then
                'X is number Y is Alpha
                Return -1
            ElseIf Not IsNumeric(x) And IsNumeric(y) Then
                'X is Alpha Y is Number
                Return 1
            Else
                'Both Alpha
                Return String.Compare(x, y)
            End If
        End Function
    End Class

This looks at two values at a time. If they are both numeric then we do a normal numeric compare. If they are both non-numeric we do a normal string compare. If one is numeric and the other one isn't we know the numeric value is 'less than' the non-numeric value.

To use this comparer class use it as a argument in the Sort() function.

VB.NET:
list.Sort(new MyComparer)
 
I think rcombs4 is on the right track but I don't think that specific implementation is going to work. None of the values in your list are numeric so you'll still get the same result. What you need to do is determine whether the values START with a number and, if they do, compare by that number first.
VB.NET:
Public Class NumericStringComparer
    Implements IComparer(Of String), IComparer

    Public Overloads Function Compare(ByVal x As String, _
                                      ByVal y As String) As Integer Implements IComparer(Of String).Compare
        Dim xNumberLength As Integer = 0
        Dim yNumberLength As Integer = 0

        'Get the length of the numeric prefix on the first string.
        While xNumberLength < x.Length AndAlso Char.IsDigit(x(xNumberLength))
            xNumberLength += 1
        End While

        'Get the length of the numeric prefix on the second string.
        While yNumberLength < y.Length AndAlso Char.IsDigit(y(yNumberLength))
            yNumberLength += 1
        End While

        Dim result As Integer = 0

        If xNumberLength = 0 AndAlso yNumberLength = 0 Then
            'Neither string has a numeric prefix so just compare as strings.
            result = x.CompareTo(y)
        ElseIf xNumberLength = 0 Then
            'The first string has no numeric prefix so the second string comes first.
            result = 1
        ElseIf yNumberLength = 0 Then
            'The second string has no numeric prefix so the first string comes first.
            result = -1
        Else
            Dim xNumber As Integer = Integer.Parse(x.Substring(0, xNumberLength))
            Dim yNumber As Integer = Integer.Parse(y.Substring(0, yNumberLength))

            'Compare the numeric prefixes as numbers.
            result = xNumber.CompareTo(yNumber)

            If result = 0 Then
                'The numeric prefixes are the same so compare the rest of the strings.
                result = x.Substring(xNumberLength).CompareTo(y.Substring(yNumberLength))
            End If
        End If

        Return result
    End Function

    Public Overloads Function Compare(ByVal x As Object, _
                                      ByVal y As Object) As Integer Implements IComparer.Compare
        Return Me.Compare(CStr(x), CStr(y))
    End Function

End Class
 
I know my solution wasn't the correct impementation, but why are the values in his list not considered numeric?
 
I know my solution wasn't the correct impementation, but why are the values in his list not considered numeric?
I think that you must be assuming that the parts after the dashes are not part of the items but I think you'll find that they are, e.g. "1 - Value for 1" is the whole item as opposed to the item being "1" and the rest being just a description added for the benefit of the post.
 
Back
Top