mjn has asked for the wisdom of the Perl Monks concerning the following question:

I have a cgi which is parsing a csv file and displaying the data. It works great and has been satisfactory for a good many months. The people who requested the original work now are asking me to provide a few different views for the data. As it stands the data structure looks like this:

@{$data_struct{$build_no}} = ($build_name,$campus,$audit_date,$cutover +_date,$im)

Primary key is the building number. This is unique. Since the building number is alpha numeric this is the sort i am using:

return $a =~ /^\w/ ? ($b =~ /^\w/ ?$a cmp $b : 1) : $a <=> $b;

It works fine but I am looking to provide the exact same information but sort(or resort) by building_name or cutover_date.

Has anyone done this sort of thing for hashrefs and can I do it without multiple data transformations? I am really lost as to how to do this...

Help, as always, is much appretiated.

_____________________
mjn

Replies are listed 'Best First'.
(jeffa) Re: Sorting Complex Data Scructures
by jeffa (Bishop) on Sep 14, 2001 at 02:14 UTC
    Sounds like you need to check out DBD::CSV. Then you can use SQL to extract the data you want. Good stuff.

    jeffa

Re: Sorting Complex Data Scructures
by TGI (Parson) on Sep 14, 2001 at 02:27 UTC

    Well, it's all in the sort sub.

    # Sort a list of building ids alpha by name @sorted_ids = sort {$data_struct{$a} cmp $data_struct{$b}} keys(%data_ +struct);
    The date issue is a little tougher, I recommend turning the date into unix time and sorting numerically. Use the Time::Local module's timelocal command to do the conversion. The exact code will vary depending on your date representation. $time = timelocal( $sec, $min, $hours, $mday, $month, $year) Note that the year representation is like that of time(), so subtract 1900 from the year, eg 2001 = 101.


    TGI says moo

Re: Sorting Complex Data Scructures
by derby (Abbot) on Sep 14, 2001 at 02:26 UTC
    mjn,

    Although your code is a hash and not a reference to a hash, the below should give you some idea on how to approach the problem.

    #!/usr/local/bin/perl -wd $x = { z => [ 'lucy', 'umcp', '1999', '2000', 'z' ], a => [ 'charlie', 'umuc', '2001', '1999', 'a' ], x => [ 'schroeder', 'umbc', '1976', '2005', 'e' ], }; @b = sort { $a cmp $b } keys %$x; @c = sort { $x->{$a}[0] cmp $x->{$b}[0] } keys %$x; @d = sort { $x->{$a}[2] cmp $x->{$b}[2] } keys %$x; print "done";
    -derby
Re: Sorting Complex Data Scructures
by gt_reynolds (Initiate) on Sep 14, 2001 at 02:34 UTC
    A while ago I had a similar problem, involving analysis of the perfomance of football (soccer) players. Their performance stats were stored in a multilevel hash, the final key of which was their name. I wanted a list of the players in order of performance on a particular statistic, which is similar you your situation. Here is a bit of the code i used.
    @players; # list of names @keys = sort { $data{$half_query}{$stat_query}{$b} #compares on statistic <=> $data{$half_query}{$stat_query}{$a} || $a cmp $b # if they are equal compare on name } @players;
    Hope that helps! Greg.
Re: Sorting Complex Data Scructures
by blakem (Monsignor) on Sep 14, 2001 at 02:24 UTC
    Warning untested code below:

    for my $build_no (sort { $data_struct{$a}->[0] cmp $data_struct{$b}->[0] } (keys %data_struct) ) { print "$build_no => $data_struct{$build_no}->[0]\n"; }

    -Blake