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

Hello monks,
I've dumped the following data structure to show my problem below:
$VAR1 = 'cycVolumeSetActivity'; $VAR2 = { '1' => 'reconstruct', '2' => 'initialize', '3' => 'verify', '10' => 'mirrorCreate', '4' => 'spareTest', '11' => 'migration', '5' => 'scheduledReconstruct', '12' => 'expansion', '6' => 'scheduledInitialize', '7' => 'scheduledVerify', '8' => 'scheduledSpareTest', '9' => 'mirrorBreak' };
I'm using the following code to sort my hash of hashes by key. I'm trying to get the numerical keys in order for printing. see below:
foreach my $key ( keys %event_hash ) { print "$key: { "; for my $key2 ( sort keys %{ $event_hash{$key} } ) { sort { keys %{$event_hash{$key}{$b}} cmp keys %{$event_hash{$key}{ +$a}} } keys %event_hash; print "$key2=$event_hash{$key}{$key2} "; } print "}\n"; }
It's not sorting them numerically, does anyone know why?

Thanks

Replies are listed 'Best First'.
•Re: Numerical sorting issues with a hash of hashes
by merlyn (Sage) on Jul 22, 2003 at 14:31 UTC
      hmm...I cleaned it up with the follwoing code:
      foreach my $key ( keys %event_hash ) { print $key, "\n"; for my $key2 ( keys %{ $event_hash{$key} } ) { sort { $a <=> $b } print "$key2=$event_hash{$key}{$key2}\n"; } print "\n"; }
      and the output still isn't sorted:

      OUTPUT

      cycVolumeSetActivityState 1=started 2=startedAutofix 3=completed 10=deleted 4=completedWithMiscompares 11=priorityChanged 5=abortedDueToIOError 20=running 12=scheduled 6=abortedDueToIOErrorWithMiscompares 21=aborted 13=modified 7=abortedByOperator 14=failedToStart 8=abortedByOperatorWithMiscompares 9=failed 15=abortedNoMemory 16=restarted 17=suspended 18=resumed 19=stopped
        You need to call sort in your for condition It only needs a small change to sort out
        foreach my $key ( keys %event_hash ) { print $key, "\n"; for my $key2 ( sort { $a <=> $b } keys %{ $event_hash{$key} } ) { + print "$key2=$event_hash{$key}{$key2}\n"; } print "\n"; }
Re: Numerical sorting issues with a hash of hashes
by simonm (Vicar) on Jul 22, 2003 at 15:04 UTC

    You're using sort in a null context.

    Sort doesn't permanently change the order of something, it just gives you back a sorted copy. In your original code, the first sort gets used by the foreach, but nothing happens to the results of the second sort, it's just thrown away (aka "null context").

    Assuming you just want to print the contents of the inner hashes in numeric key order, try something like the following:

    foreach my $key ( keys %event_hash ) { print "$key: { "; foreach my $key2 ( sort { $a <=> $b } keys %{ $event_hash{$key} } ) +{ print "$key2=$event_hash{$key}{$key2} "; } print "}\n"; }
Re: Numerical sorting issues with a hash of hashes
by Kageneko (Scribe) on Jul 22, 2003 at 14:36 UTC
    cmp does a string comparison. <=> does a numerical comparison. I could give a bit more help if I saw more of your code, since some if it is confusing me. For instance, this:
    sort { keys %{$event_hash{$key}{$b}} cmp keys %{$event_hash{$key}{$a}} + } keys %event_hash;
    will sort based on the number of keys in the subhashes, not their value. (or so I think, since output of keys will be cast scalar by the cmp operator, yes?)
Re: Numerical sorting issues with a hash of hashes
by BrowserUk (Patriarch) on Jul 22, 2003 at 21:37 UTC

    Is there any particular reason tha you aren't using an array rather than a hash? With contiguous numeric keys, there using an array is slighly more efficient to reference, but best of all, you don't need to sort anything to iterate them in numeric sequence.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller