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 Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Sorting a two-dimensional array

Status
Not open for further replies.

Meatsim

Programmer
Oct 9, 2001
13
US
Hello folks, I’m having difficulty in sorting a two-dimensional array. Right now, it looks something like this:

Code:
Author[0] |	Program[1] |	Date[2] |	Notes[3 – end]
jdoe 		sample.c	01/01/01	A sample program[3] That does things[4]
jeffk		l33t.c		03/25/00	Another Program[3]

…etc.

For the moment, I’d like to sort by author first, then by program, but I’d also like this system to be somewhat flexible so that I can change the sort order later. I have gotten this list to sort properly if I leave out the “notes” portion and place the Author, Program, and Date fields on a single, tab-delimited line, but I’d like to know how to sort by a particular element of a two-dimensional array so that I can leave the notes where they are.

Thanks!
-Meatsim
 
Hi,
Its called a pointer or index sort. You build another array of integers from 1 to number of records. Then you call

@intarray = sort mycmp @intarray;

in mycmp you will get 2 values. The subscripts of your original array to ask you to return negative, zero, or positive to figure out how to order them. The come in as $a and $b.

sub mycmp
{

# obtain the values from the original array using the int subscripts

($autha,$programa,$datea,$notesa) = split(/\t/,$myarray[$a]);
($authb,$programb,$dateb,$notesb) = split(/\t/,$myarray[$b]);


if ( $autha < $authb )
{
return -1;
}
elsif ( $autha > $authb )
{
return 1;
}

# OK authors are equal now compare whatever

.
.
.

# everything I wanted to compare is equal

return 0;
}


then after the sort is done to see the list in sorted order you must use the extra level of intarray

foreach $i ( @intarray )
{
print $myarray[$i];
}

 
Hi tdatgod - thank you very much for the sorting algorithm, but it's still not quite working. When I split the line by \t, the split doesn't appear to function - printing out $autha gives me an array location, but printing $programa, $datea, etc gives me nothing. Are elements in a 2d array split by \t?

Thanks!
-Meatsim
 
Try it using the 'cmp' operator that is a shortcut for comparing alphabetic strings.


@myarray=sort {
($autha,$programa,$datea,$notesa) = split(/\t/, $a);
($authb,$programb,$dateb,$notesb) = split(/\t/, $b);

return( $autha cmp $authb );
} @myarray;



 
Oh, wait...if I have all that stuff in an array, then I can just set $autha = $myarray[$a][0] and so on! I feel silly.

Also, thanks for the cmp tip, badco - that'll save lots of time running this script.
 
HI,
return( $autha cmp $authb );

will work if you only want to sort the array on Author. however you might want to modify this a little by

$c = $autha cmp $authb
if ( $c != 0 ) { return $c }

#authors were equal compare program

$c = $proga cmp $progb
if ( $c != 0 ) { return $c }

# programs were equal compare dates


$c = $datea cmp $datesb
if ( $c != 0 ) { return $c }

#everything compares equal

return 0;

Also remember at any point if you want to reverse the sort order reverse the order of the comparators or return the opposite of result value.

$c = $fieldb cmp $fielda;
or
if ( $c != 0 ) { return -($c) }

Don't do both or you will cancel the reverse effect out.


--

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top