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
Solved

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

Posted on 2004-10-12
7
421 Views
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)
     pAArraylist.add(AtoAdd)
   end function
end class

dim myB as new b

dim myA as new a
myA.a1 = "Hello World"
myA.a2 = 1
myB.addA(myA)

myA.a1 = "Goodbye"
myA.a2 = 2
myB.addA(myA)

myA.a1 = "Hello World"
myA.a2 = 3
myB.addA(myA)

What I want to do now is be able to say something like:
myB.sort(sortByA1)

or

myB.sort(sortByA2)

or

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!!!

0
Comment
Question by:majnun
  • 2
  • 2
7 Comments
 
LVL 7

Accepted Solution

by:
ramesh12 earned 250 total points
ID: 12293492
0
 
LVL 7

Expert Comment

by:ramesh12
ID: 12293582
0
 
LVL 12

Assisted Solution

by:farsight
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. ( http://www.devguru.com/Technologies/jetsql/quickref/order_by.html )

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.
0
 
LVL 12

Expert Comment

by:farsight
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.
0
 

Author Comment

by:majnun
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?

Thanks!
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Introduction When many people think of the WebBrowser (http://msdn.microsoft.com/en-us/library/2te2y1x6%28v=VS.85%29.aspx) control, they immediately think of a control which allows the viewing and navigation of web pages. While this is true, it's a…
Creating an analog clock UserControl seems fairly straight forward.  It is, after all, essentially just a circle with several lines in it!  Two common approaches for rendering an analog clock typically involve either manually calculating points with…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

809 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