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

Good Afternoon - This is my first post here - and I am relatively new to Perl - so please be patient/kind if it is in the wrong place..... I have created a structure (within a program) that looks like....
$the_data[$datapointcnt] = { x => $maturity_range_counter, y => $oas, rating => $rating, cusip => $cusip, description => $description, maturity => $maturity, maturity_yrs => $maturity_yrs, maturity_sort => $maturity_sort, oas => $oas, rich_cheap => $rich_cheap};
where the structure is loaded correctly with data. I would like to end up with a similar structure sorted first by the maturity_sort and secondly by rich_cheap. rich_cheap is a numeric value. I saw some of the code in the O'Reilly Cookbook (4.14 & 4.15) and was a little confused with the map/sort/map. Can anyone shed some light on how the code would be structured to accomplish the desired sort. Many thanks. Andrew

Replies are listed 'Best First'.
Re: Sorting
by japhy (Canon) on Feb 12, 2002 at 21:09 UTC
    Ooooh! CUSIPS! I worked at RiskMetrics for several months, so I know about these. Fun stuff. Anyway, you might want to look at my Resorting to Sorting tutorial. That should help you set up a sorting routine. You shouldn't need a Schwartzian Transform, but merely a multi-tiered sort() block.

    _____________________________________________________
    Jeff[japhy]Pinyan: Perl, regex, and perl hacker, who could use a job
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

Re: Sorting
by vladb (Vicar) on Feb 12, 2002 at 19:24 UTC
    You may try doing something like this:
    use strict; my @the_data = ( { field1 => 'first item', field2 => 8, field3 => 'z', }, { field1 => 'second item', field2 => 2, field3 => 'b', }, { field1 => 'third item', field2 => 6, field3 => 'c', }, ); # sort @the_data by field2 and field3... for ( sort { ($$a{field2} <=> $$b{field2}) && ($$a{field3} cmp $$b{fie +ld3}) } @the_data ) { print $$_{field1} . "\n"; }
    The output that I get is:
    second item third item first item
    In your case, you may have maturity_yrs in place of field2 and rich_cheap instead of field3 inside my sort statement. You can sort your structures in any imaginable way using the sort and your own custom built sort subroutines.

    "There is no system but GNU, and Linux is one of its kernels." -- Confession of Faith
Re: Sorting
by rjray (Chaplain) on Feb 12, 2002 at 22:48 UTC

    It is a good idea to read the links the others have provided. In the meantime, the following should get you over this hump. It assumes that the function maturity_sort behaves like a proper sort function (returns <0 for a < b, returns >0 for a > b, and 0 for a == b), and that it takes the full record, not just the "maturity" key:

    my $tmp; # to avoid allocation every loop iteration @sorted = sort { ($tmp = maturity_sort($the_data{$a}, $the_data{$b})) ? $tmp : ($the_data{$a}->{rich_cheap} <=> $the_data{$b}->{rich_cheap}); } (keys %the_data);

    --rjray