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

I'm using the follwoing snippet from my data structure:
$VAR1 = '# clusterXWLBSTrapApplicationFail'; $VAR2 = { 'varbinds' => [ '1.3.6.1.4.1.1302.3.7.2.17(1,0)\\:# clxTrapD +ataWLBSClusterName', '1.3.6.1.4.1.1302.3.7.2.16(2,0)\\:# clxTrapD +ataWLBSNodeName', '1.3.6.1.4.1.1302.3.7.2.20(3,0)\\:# clxTrapD +ataApplicationName', '1.3.6.1.4.1.1302.3.7.2.21(4,0)\\:# clxTrapD +ataApplicationFailure', '1.3.6.1.4.1.1302.3.7.2.22(5,0):# clxTrapDat +aApplicationAction' ], 'oid' => '1.3.6.1.4.1.1302.3.7.6.10' }; $VAR3 = '# clusterXTrapNormalCSLog'; $VAR4 = { 'varbinds' => [ '1.3.6.1.4.1.1302.3.7.2.8(1,0)\\:# clxTrapEv +entDate', '1.3.6.1.4.1.1302.3.7.2.9(2,0)\\:# clxTrapEv +entTime', '1.3.6.1.4.1.1302.3.7.2.10(3,0)\\:# clxTrapE +ventSource', '1.3.6.1.4.1.1302.3.7.2.11(4,0)\\:# clxTrapE +ventCategory', '1.3.6.1.4.1.1302.3.7.2.12(5,0)\\:# clxTrapE +ventID', '1.3.6.1.4.1.1302.3.7.2.13(6,0)\\:# clxTrapE +ventUser', '1.3.6.1.4.1.1302.3.7.2.14(7,0):# clxTrapEve +ntComputer' ], 'oid' => '1.3.6.1.4.1.1302.3.7.6.7' };
I'm trying to sort the hash by its 'oid' key, any suggestions? will perls sort handle the oid string as a numerical comparison?

Replies are listed 'Best First'.
Re: sort hash by value
by Joost (Canon) on Jul 10, 2003 at 14:52 UTC
    How about:
    my @sorted_keys = sort { $hash{$a}->{oid} cmp $hash{$b}->{oid} } keys +%hash;
    which will sort with string comparison because of the use of cmp use <=> if you want numerical comparison, but note that the 'oid' field has a non-numerical value.
    -- #!/usr/bin/perl -w use strict;$;= ";Jtunsitr pa;ngo;t1h\$e;r. )p.e(r;ls ;h;a;c.k^e;rs ";$_=$;;do{$..=chop}while(chop);$_=$;;eval$.;
Re: sort hash by value
by ant9000 (Monk) on Jul 10, 2003 at 14:50 UTC
    The function
    sub fmt($){ join("", map { sprintf "%05d", $_ } split(/./, shift)); }
    should format the oids you have in a form suitable for comparison, as long as no subkey of the oid is longer than 5 digits (adjust it otherwise).

      To expand on ant9000's answer, his function will help in making a comparison tag. He's building a string which has all the numbers in fixed-width columns so that the string comparison operator will naturally order according to numerical fields. To use it to sort by those tags, you'd apply the schwartzian transform:

      my @keys_sorted_by_converted_value = map { $_->[0] } sort { $a->[1] cmp $b->[1] } map { [ $_, fmt($hash{$_}) ] } keys %hash;

      --
      [ e d @ h a l l e y . c c ]

        You're right: reading again my post, I find it quite cryptic myself... sorry.
        The idea is the following:
        @sorted_keys=sort { fmt($hash{$a}->{oid}) <=> fmt($hash{$b}->{oid}) } keys %hash;
        where fmt is defined as above (with the correction in split below, sure!). You can also use cmp instead of <=>, if you wish.
      Anyidea why tis sub is failing...I'm passing it an oid string like so:
      my $foo = fmt($oid); print "FOO: $foo\n"; sub fmt($){ join("", map { sprintf "%05d", $_ } split(/./, shift)); }
      Thanks!
        Just a wild guess, but I don't think split /./ is going to do what you want. I think you want split /\./ (note the \, escaping the "match anything" .)
        --
        Mike
Re: sort hash by value
by archon (Monk) on Jul 10, 2003 at 14:51 UTC

    No, you would have to write your own sort routine to compare them. I suggest splitting the OID up on the dots, looking for the first difference, and compare those two elements numerically.

    Keep in mind that you can't really 'sort' the hash itself. You can only display a sorted representation of the hash.