Link to home
Start Free TrialLog in
Avatar of Gene Moody
Gene MoodyFlag for United States of America

asked on

How to sort a List of Non-Generic Data?

Hi Experts!

I have a structure that I make a list of to contain basic inventory stuff.  It looks a lot like this:
    Public Structure inventoryPartInfo
        Dim partNumber As String
        Dim partDescription As String
    End Structure

Open in new window


...and I'm really digging the List (of T) feature in VB.Net to allow me to more cleanly deal with my arrays of Inventory Parts:
    Dim microController As New List(Of inventoryPartInfo)

Open in new window


To add a "row" of data to this List is really pretty simple:
    Dim newControl As New inventoryPartInfo

    newControl.PartNumber = "11435-AC-AB-X"
    newControl.PartDescription = "Cirrus Dual-Band Gate"

    microController.Add (newControl)
    newControl = Nothing

Open in new window


...now, I have a need to sort this list, but the default List.Sort() fails because it's trying to compare two structs, and has no default method for this.  All of the examples I keep running into are for "Generic" data, which almost always refers to a list (Of String) or a list (Of Integer) - neither of which apply here.  I've been studying Lambda functions, but nothing I attempt seems to meet with anything other than an error condition.

If my input data looks like this:
          11435-AC-AB-X     Cirrus Dual-Band Gate
          23907-FX-BA-W     Rabbit Data Manifold
          21340-TF-AB-A     Drax Ring Buffer
          54384-FX-BA-A     Prillex Transfer Enhancer

Open in new window


...I need to be able to sort it (on PartDescription) to look like this:
          11435-AC-AB-X     Cirrus Dual-Band Gate
          21340-TF-AB-A     Drax Ring Buffer
          54384-FX-BA-A     Prillex Transfer Enhancer
          23907-FX-BA-W     Rabbit Data Manifold

Open in new window


...maybe later I might need to sort it (on PartNumber), but that is obviously a string, too, so the same [sort] function might apply, only to a different "field" value (PartNUmber) instead of (PartDescription).

Does anybody know how this may be achieved?  I'm fairly certain that it's something small that I'm overlooking - I can't shake the feeling that this should be pretty simple.

Thanks for your assistance!
- The Lurking LongFist
Avatar of Neil Russell
Neil Russell
Flag of United Kingdom of Great Britain and Northern Ireland image

Rather than just using a plain structure, use a class. Then you can override methods such as .ToString etc....

See a very good clear example here....

http://www.vbforums.com/showthread.php?t=310363
Implement IComparer interface:

    Public Class CompInventoryPartNumber
        Implements IComparer(Of inventoryPartInfo)

        Public Function Compare(x As inventoryPartInfo, y As inventoryPartInfo) As Integer Implements System.Collections.Generic.IComparer(Of inventoryPartInfo).Compare
            Return String.Compare(x.partNumber, y.partNumber)
        End Function
    End Class

Open in new window


use like this:

microController.Sort(New CompInventoryPartNumber)
Avatar of kaufmed
This is a bit off topic, but...

Rather than just using a plain structure, use a class. Then you can override methods such as
Is there something I don't know about which prevents one from overriding methods in a struct?

Public Structure inventoryPartInfo
    Dim partNumber As String
    Dim partDescription As String

    Public Overrides Function ToString() As String
        Return "Hello World!"
    End Function
End Structure

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Except that with IComparer, it's easy to have multiple sort types... One for part number one for description.

Public Class CompInventoryPartDescription
    Implements IComparer(Of inventoryPartInfo)

    Public Function Compare(x As inventoryPartInfo, y As inventoryPartInfo) As Integer Implements System.Collections.Generic.IComparer(Of inventoryPartInfo).Compare
        Return String.Compare(x.partDescription, y.partDescription)
    End Function
End Class

Open in new window

Avatar of Gene Moody

ASKER

Absolutely accurate; minimized code changes and/or extensions (which is GREAT since I had no control over how the code was originally written --- I'm just the maintenance operator today) and made it very easy for me to read and understand.

The others were close - and don't think I didn't appreciate their input - but this was the solution that resolved the problem with the least amount of code invasion, which results in fewer bugs later on.

Excellent work!  And thank you!
but this was the solution that resolved the problem with the least amount of code invasion, which results in fewer bugs later on.
But you've actually modified the behavior of the structure itself. I'd say that has the potential for a bug. With PaulHew's approach, you are adding a new entity which contains the functionality you desire, but does not modify the original structure definition--it's completely separate. And as he already mentioned, that approach is much more extensible/expandable than implementing IComparable would be.
Definitely lots of good points in the discussion here...