Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VB.NET sort IEnumerable class

I want to sort a VB class that implements IEnumerable. I don't want a new object / linq. It must stay as the original object but sorted. Here is a sample class.

Public Class Person
    Public Sub New(ByVal fName As String, ByVal lName As String)
        Me.firstName = fName
        Me.lastName = lName
    End Sub

    Public firstName As String
    Public lastName As String
End Class

Public Class People
    Implements IEnumerable(Of Person)

    Private _people() As Person

    Public Sub New(ByVal pArray() As Person)
        _people = New Person(pArray.Length - 1) {}

        Dim i As Integer
        For i = 0 To pArray.Length - 1
            _people(i) = pArray(i)
        Next i
    End Sub

    Public Function GetEnumerator() As IEnumerator(Of Person) _
            Implements IEnumerable(Of Person).GetEnumerator
        Return DirectCast(_people, IEnumerable(Of Person)).GetEnumerator
    End Function

    Private Function System_Collections_GetEnumerator() As IEnumerator _
            Implements IEnumerable.GetEnumerator
        Return Me.GetEnumerator
    End Function
End Class

I know I can use LINQ but then I get a new object not the original sorted. There are too many places that use the global "peopleList" object so I need to sort the "peopleList" not a new sorted list of "People".

Dim peopleList As New People({ _
    New Person("John", "Smith"), _
    New Person("Jim", "Johnson"), _
    New Person("Sue", "Rabon")})
Dim newPeopleList = From person In peopleList Order By person.firstName Select person
'OR
Dim newPeopleList = DirectCast(peopleList, IEnumerable(Of Person)).ToList()
newPeopleList.Sort(Function(p1, p2) p1.firstName.CompareTo(p2.firstName))

I need something more like the following.

Dim peopleList As New People({ _
    New Person("John", "Smith"), _
    New Person("Jim", "Johnson"), _
    New Person("Sue", "Rabon")})
peopleList = peopleList.Sort(Function(p) p.firstName)

I know IEnumerable does not have a Sort method. I am only showing it as an example. I do have the option to modify the "People" class but in the end it must still implement IEnumerable because I don't want to break the current callers. Also the current callers must be able to see the "peopleList" sorted.

like image 661
goroth Avatar asked Sep 02 '26 18:09

goroth


1 Answers

You can sort the Person objects as you're creating the People list:

Public Sub New(ByVal pArray() As Person)
    _people = New Person(pArray.Length - 1) {}

    Dim i As Integer = 0
    For
    For Each person In pArray.OrderBy(Function(p) p.firstName)
        _people(i) = person
        i = i + 1
    Next i
End Sub

Alternatively, you can provide your own method to sort the internal array after it has been created. Something like this should work:

Public Class People
    Public Sub Sort(Of T As IComparable)(KeySelector As Func(Of Person, T))
        Array.Sort(_people, Function(x, y) KeySelector(x).CompareTo(KeySelector(y)))
    End Sub
End Class

And you can call the like like this:

peopleList.Sort(Function(p) p.firstName)
like image 140
p.s.w.g Avatar answered Sep 04 '26 07:09

p.s.w.g



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!