Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to sort an all-digit matrix 1

Status
Not open for further replies.

whn

Programmer
Oct 14, 2007
265
US
Hi Experts,

Assume there is an m by n all-digit matrix:
Code:
X11 X12 ... X1n
X21 X22 ... X2n
...
Xmn Xmn ... Xmn
I need help to write a method that somewhat like 'order by' in ansi sql. This method shall be able to sort the matrix by ANY number of column indices passed in at cmdline.

For example, if cmdline is:

% myOrderby -col 1,2,5
It'll sort the matrix by column 1, 2, & 5.

However, if cmdline is
% myOrderby -col 1,4,8,11
It'll sort the matrix by column 1, 4, 8, & 11.

I know how to implement the method if there was a fixed maxium number of columns to "order by". I am looking for a method that can sort a matrix based on any number of columns that are ordered by.

Thanks for help.
 
This should give you a start, you'll probably want to do a bit more error checking in the sort subroutine, but a custom sort seems like the way to go. The sort sub below uses recursion to deal with the unknown number of columns that will be used to sort.

Since I'm not entirely sure what you're trying to do, please test this and make sure it does what you expect.

Perl:
my @sort_by_cols = (1,3);	# You would get these from the command line
my @records = ( [qw/a1 a2 e3 a4 a5/],
		[qw/a1 b2 b3 b4 b5/],
		[qw/c1 c2 c3 c4 c5/],
		[qw/d1 d2 d3 d4 d5/],
		[qw/d1 e2 c3 e4 e5/] );			

print "BEFORE:\n";
print join(" ", @{$_} , "\n") for @records;

print "\nAFTER:\n";
my @sorted = sort {sort_sub(@sort_by_cols)} @records;
print join(" ", @{$_} , "\n") for @sorted;

sub sort_sub {
	my $sort_col = shift;
	my $sort_idx = $sort_col - 1;	# May not be necessary to subtract 1
	
	if ($a->[$sort_idx] eq $b->[$sort_idx]) {
		if (scalar @_) {
			return &sort_sub(@_);
		} else {
			return 0;
		}
	} else {
		return $a->[$sort_col - 1] cmp $b->[$sort_col - 1];
	}
}
 
Oops, use this instead (works the same, but less changes if $sort_idx needs to be updated.)

Perl:
sub sort_sub {
	my $sort_col = shift;
	my $sort_idx = $sort_col - 1;	# May not be necessary to subtract 1
	
	if ($a->[$sort_idx] eq $b->[$sort_idx]) {
		if (scalar @_) {
			return &sort_sub(@_);
		} else {
			return 0;
		}
	} else {
		return $a->[[b][blue]$sort_idx[/blue][/b]] cmp $b->[[b][blue]$sort_idx[/blue][/b]];
	}
}
 
Wow! It's amazing!!
Thank you so much, rharsh!!

But I still need a bit time to digest your solution.
 
You're welcome, let me know if I can answer any questions for you.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top