[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

Re: [MacPerl] sorting algorithms




Scott Godin wrote:

> $master_maps_list{$gametype}{lc($title)} = [$filename, $title, $size,
> $review, $rating];
> how do I sort this data by $size and then by $filename/$title for the subset
> of one of the five $gametype's ?

> basically, for a single gametype, I'd like to optionally sort the maplist
> for that gametype first by rating, and second by filename or title, so that
> all the n-rated maps are sorted alphabetically instead of arbitrarily.

Here's an attempt to create what you want:

# first some sample data: I've not tried to condense things too much
# in the hope that it makes the process somewhat clearer. The only real
# difficulty with such a data structure is pinpointing the piece that
# you wish to use in the comparison.

$gametype='assault';
$master_maps_list{$gametype}{'a'}=['a','titlea',60,'y',9];
$master_maps_list{$gametype}{'b'}=['b','titleb',73,'n',8.5];
$master_maps_list{$gametype}{'c'}=['c','titlec',51,'n',9.5];
$master_maps_list{$gametype}{'d'}=['d','titled',51,'n',9.5];
$master_maps_list{$gametype}{'aa'}=['aa','titled',51,'n',9.5];

# first a reference to allow less typing in what follows.

$ref=\%{$master_maps_list{$gametype}};

# the "sort block" below compares file size first (index 2 of the array)
# and then filename (index 0) if the file size is equal. That is, if the
# first comparison returns a zero. This just plays on the short circuit
# behaviour of the || operator; if it gets a "true" result from the first
# chunk (the <=> piece) it returns that value, which will be 1 or -1 ; if
# not, it has to evaluate the second part to see if the overall expression
# is true or false, so it compares file names. You can also throw the
# contents of this block into a subroutine -- say mysort() -- and call it
# using     @sorted = sort mysort keys %{$ref}

@sorted = sort 

{ $ref->{$a}[2] <=> $ref->{$b}[2]
                || 
  $ref->{$a}[0] cmp $ref->{$b}[0] }

    keys %{$ref}; 

# now print out the sorted values...

foreach(@sorted){
my $string= join " :: ",@{$ref->{$_}};  # join the entries of the array
print $string,"\n";
} 

# Cheers,
#         Paul


# ===== Want to unsubscribe from this list?
# ===== Send mail with body "unsubscribe" to macperl-request@macperl.org