VB .NET:Implement a sort on a class's arraylist property, with different sorting schemes

Posted on 2004-10-12
Last Modified: 2008-01-16
I have a class b, that holds an arraylist of another class a. I want to be able to sort the arraylist in class b, based on various properties of each of the a class object it holds.

By way of psuedo-code example:

class a
   public property a1 as string...
   public property a2 as integer...
end class

class b
   private pAArraylist as arraylist

   public property AArraylist as arraylist
      get() return pAArraylist
      set(value) pAArraylist = value
   end property

   public function addA(AtoAdd as a)
   end function
end class

dim myB as new b

dim myA as new a
myA.a1 = "Hello World"
myA.a2 = 1

myA.a1 = "Goodbye"
myA.a2 = 2

myA.a1 = "Hello World"
myA.a2 = 3

What I want to do now is be able to say something like:




myB.sort(SortByA1 then sortByA2)

So when i loop through the myB.AArraylist it is sorted based on the various .sort functions explained above.

I hope this is clear.

Thanks for any help!!!

Question by:majnun
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2

Accepted Solution

ramesh12 earned 250 total points
ID: 12293492

Expert Comment

ID: 12293582
LVL 12

Assisted Solution

farsight earned 250 total points
ID: 12293712
That answer is right on.
You'll need to implement three comparer classes, one for A1, one by A2 and one for A1 then A2.
If that explodes, due to the number of different compares you need, you could make only one comparer that you create and give a sort-specification of the comparison you need at creation-time.

Dim myComparer As IComparer

myComparer = new MyTypeNameComparer("A1")
Array.Sort(myTypeArray, myComparer)

myComparer = new MyTypeNameComparer("A2")
Array.Sort(myTypeArray, myComparer)

myComparer = new MyTypeNameComparer("A1,A2")
Array.Sort(myTypeArray, myComparer)

This will be more flexible, but slower, since it needs to figure out what kind of compare to do each time CompareTo is called.  That can be partially fixed, by making class MyTypeNameComparer into a factory class that returns a dedicated comparer for the common cases, like "A1" or "A2", and a more generic comparer that interprets the sort-spec for the complicated or rare cases, like; "A5,A7,A1,A2".  Note that it's up to you to define the sort-specification, so you can make it handle ascending and/or descending sorts.  You might consider using the SQL Order By clause as a model. ( )

Finally, you might consider creating and using sorted views into your base data, instead of actually resorting the base data.  This has the advantages: (1) Your base data is not moved ... especially usefully if you have huge amounts of data. (2) It permits multiple simultaneous views, each sorted differently, into the same base data.  To implement, each view is essentally an index to the base data, and the comparer must compare using the data pointed to by the index, rather than my the index number itself.  Ask if you need more help to implement this.
LVL 12

Expert Comment

ID: 12293825
P.S.  This sounds a lot like what ADO.Net DataTable and DataView do via DataView.Sort().  Depending on your application, it might make sense to reuse this existing functionality.

Author Comment

ID: 12298614
Yeah it does seem like a lot of work...

Here's the particular nature of the problem I am trying to solve... I have a rather complicated database driven application that I have been using Access as a front end and back end for, and i am begining to feel the pain of VBA and so am switching slowly over to using VB .NET for everything.

The group that I am working for has a habit of changing their conceptual model of the things I am using the databases to keep track of, and previously I had everything tied to forms in Access that were generated by a myriad of SQL statements. A change to their conceptual model often requires a slight but fundamental restructure of the tables, sometimes adding new ones and new relationships... however, many of the functionalities of what I need to do with the data once I have generated an SQL query generally doesn't change.

I tried to create classes in VB that could abstractly represent the data, and build an "initialize" function for container class that connected to the databases, and populated the contained class's properties with data returned by SQL statements. And to create relationships between classes I created arraylists to hold sub classes.

For example, there is a series of tables representing albums and audio tracks. I created a class which held audio track objects (with properties such as Title, Artist, Duration, etc.) which in turn was shoved in an object based on an Album class (with a "trackArraylist" property, as well as properties such as album name, etc.) And the album class objects were in turn shoved into a "library class" which has an Album Arraylist, and an initialize() fuction which connects to the database and populates all these objects. This is a more simplified version of one of the many data relationships I need to keep track of.

My thought was that once I have these classes, I can go ahead and write code like that references these properties instead of the table views directly. This way if the structure of the database changes I can simply change how these properties are populated in the initialize function of the container class, and worse case if a property becomes obsolete I can just populate that property with an empty string, or 0, or some other "non-filled in" value.

I was hoping in this way to limit the amount of recoding when the database conceptual model and structure changes.

I was hoping that an Arraylist would be able to sort objects inside simply by refereing those object's properties which have standard types (like strings, integers, etc.) For instance if track myAlbum(x).title was "Bob's Song" it seems logical that if myAlbum(y).title is "Sally's Song" that the track myAlbum(x) would come before track myAlbum(y). And I was hoping to write a simple function i could use to sort based on album properties, or track properties like sort(myLibrary, album.title, ascending) or sort(myLibrary, track.duration, descending) and so on. Where arg1 is the library holding the albums (which are holding the tracks), arg2 is the class (album or track) and propery I want to sort by, and arg3 is the direction of the sort.

Maybe I should just stick with datasets and datareaders.

How do other people deal with abstracting their presentation of data from the actual datasets generated from underlying tables that might change (and that in my environment WILL change)?

For instance, do people use aliases and then if a field becomes obsolete just alias an empty field for all obselete fields?


Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you're writing a .NET application to connect to an Access .mdb database and use pre-existing queries that require parameters, you've come to the right place! Let's say the pre-existing query(qryCust) in Access takes a Date as a parameter and l…
A while ago, I was working on a Windows Forms application and I needed a special label control with reflection (glass) effect to show some titles in a stylish way. I've always enjoyed working with graphics, but it's never too clever to re-invent …
In an interesting question ( here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…
Attackers love to prey on accounts that have privileges. Reducing privileged accounts and protecting privileged accounts therefore is paramount. Users, groups, and service accounts need to be protected to help protect the entire Active Directory …

733 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question