I learned something new!

| | Comments (13)

Did you know that SortWith is actually useful? I had absolutely no clue what this was supposed to be used for. Thankfully, Mars was able to set me straight!

Basically, when you have two arrays of items that are related to one another, you can use SortWith to sort both arrays at the same time; keeping the relationship.

For example, let's say that you have two arrays: one of names of items, and one for their price. Now you want to sort the array of names, but keep the prices with their corresponding name. So, in code:
[rbcode]
dim names( -1 ) as String
dim prices( -1 ) as Double

// Setup the names and prices
names.Append( "Pear" )
prices.Append( 2.00 )
names.Append( "Apple" )
prices.Append( 1.25 )
names.Append( "Orange" )
prices.Append( 1.00 )

// Now sort based on the names, while
// keeping the prices intact.
names.SortWith( prices )[/rbcode]
The end effect of this code is that the names and prices arrays still retain their relationship; both arrays are now sorted (by name)!

How this works is simple: every time SortWith swaps two elements of the base array, it swaps the corresponding elements of the parameter array as well.

Wow, how nifty is that?

13 Comments

What happens when you do this?

names.SortWith( prices ).SortWith(names)

or

names.SortWith(prices.SortWith(names))

what implications are there? :)

You'd get a compile error since SortWith returns nothing. ;-)

I hear that SortWith doesn't return anything... so I guess it wouldn't work.

It'd be nice though right?

I love this feature.

I've been using it to replace some really awful sorting code in apps that I wrote [well, converted to RB from other languages] originally in older versions of RB.

I really enjoy replacing whole blocks of code with one line!

Russ

@Jake: A better syntax would be to accept a ParamArray.

names.SortWith(prices, names)

Would sort names by "prices", with "names" as a secondary sorting parameter.

@Adam -- which is exactly how SortWith works, I believe.

Excellent. I'm embarrassed to say I'd not really known what SortWith was good for. Now I know :)

@Aaron: sure enough. However, I think Jake and I are talking about a "secondary sort" as well, where if two items in the primary array are identical, it will fall back to sorting by the first secondary array, then the second secondary array, and so on.

Does REALbasic's SortWith behave this way? I suspect it does not.

@Will -- you were embarrassed? Imagine my consternation! :-P

@Adam -- correct, it does not. It sorts all the parameter arrays based on the base array. It does not cascade the sorts.

SortWith is a feature that I only learned to use a couple months ago. However, I have needed it for quite a while! I use a lot of completely custom classes (no supers) in apps I work on and need to sort those by some property of the class. It works beautifully for this!

For instance, those tabletop RPG gamers of you out there may be familiar with White Wolf Publishing. I've written a character management app for the new World of Darkness, complete with support for both tabletop and Live Action games.
If (for instance) I'm needing to sort a characters experience records, I can make an array from the date property of each XP Entry, or from any of the other properties, and then use SortWith to sort the XPEntries by that new array! It has made my life SOOOO much simpler! No more orderless XP logs or weapon lists!

-BluJai

Awesome! I hope I remember it the next time I need it.

@Adam - I don't know if that syntax is exactly expressive though...

neither is mine for that matter.

for cascading sorts it might make sense to do

names.SortWith(prices).Sort(SortDirection.Ascending)

or something similar...

I agree, cascading sorts could be very useful.

@Jake: Your two-part syntax doesn't make any sense, though. For example:

names.SortWith(prices).Sort(SortDirection.Ascending)

Would wort the names array with the prices array. But SortWith doesn't return anything, so it would have to be modified to return a reference to names. Then you're sorting the returned "names" array in an ascending direction, but since you no longer have the link to "prices", they'll be scrambled.

A "secondary" or cascading sort could be added to SortWIth with the current syntax at no extra trouble. I'm just not sure I think it's worth it.

Leave a comment

Disclaimer

I'm currently an employee of REAL Software. My blog is mine. The opinions represented in this blog are mine as well and may not represent my employer's opinions. All original material is copyrighted and property of the author.

REALbasic® is a registered trademark of REAL Software, Inc. REAL SQL Server™ and Lingua™ are pending trademarks of REAL Software, Inc. All rights reserved.