Hardly Armchair wrote:
>
> Hello List,
>
> I have a data structure like so:
>
> %p_mod = {
>           'A' => {
>                   'fingers' => {
>                                 '4' => 'ABSFMQS',
>                                 '5' => 'SMTFQNL',
>                                },
>                   'name'    => '8-H34'
>                  },
>           'C' => {
>                   'fingers' => {
>                                 '1' => 'ALEJIEK',
>                                 '2' => 'BESLERJ',
>                                },
>                   'name'    => '9-J09'
>                  },
>           'B' => {
>                   'fingers' => {
>                                 '3' => 'OLPWJEK',
>                                },
>                   'name'    => '6-G79'
>                  }
>          }
>
> To access the keys to the hash reference under 'fingers' ordered by the
> interior number (1 through 5) I have made this construct:
>
> foreach my $mods (reverse sort keys %p_mod) {  #first sort to go C,B,A
>     for my $position ( sort keys %{ $p_mod{$mods}{fingers} }) {
>         print "$position => $p_mod{$mods}{fingers}{$position}\n";
>     }
> }
>
> The second sort exploits the fact that the numbers will never be greater
> than 5 (due to the nature of the data), so a default sort will do the
> same thing as a numeric sort.  This is good because it is easy and, I've
> heard, using default sort is faster than any other way of sorting in
> Perl.  However, I am curious as to how this would be accomplished the
> "proper" way; that is, by numerically sorting the keys of the anonymous
> hash referenced by 'finger' (please correct this last statement if it is
> incorrect, as it reflects my understanding of the problem as it
> currently exists).
>
> So far, I've found that this "works" in the sense that the correct
> things are printed out:
>
> foreach my $mods (reverse sort keys %p_mod) {         #first sort to get
>                                                       #order C,B,A
>     for my $position ( sort {
>                              ${ $p_mod{$mods} }{$b}
>                                       <=>
>                              ${ $p_mod{$mods} }{$a}
>                             }
>                        keys %{ $p_mod{$mods}{fingers} }
>                      ) {
>         print "$position => $p_mod{$mods}{fingers}{$position}\n";
>     }
> }
>
> However, since I of course "use warnings", Perl tells me "Use of
> uninitiated value in numeric comparison (<=>) at [relevant line]...".
>
> Specifically, it prints out:
>
> Use of uninitialized value...
> Use of uninitialized value...
> 1 => ALEJIEK
> 2 => BESLERJ
> 3 => OLPWJEK
> Use of uninitialized value...
> Use of uninitialized value...
> 4 => ABSFMQS
> 5 => SMTFQNL
>
> I am so close, it's driving me nuts.  Please let me know what I am
> screwing up here.  Also, if this is a totally ridiculous way of doing
> things (like, "you're better off with THIS kind of data structure",
> etc.), you can tell me that, too.  I'm here to learn.

Hi.

John has already shown you where you were going wrong, but I'm still
uncomfortable about the magic that says that sorting the outer keys in reverse
order will present the inner keys in forward order. The code below seems much
better to me, as it doesn't rely on any such inside knowledge and also removes
one level of loop.

HTH,

Rob


my %fingers;

foreach (values %p_mod) {
  %fingers = (%fingers, %{$_->{fingers}});
}

foreach (sort { $a <=> $b } keys %fingers) {
  print "$_ => $fingers{$_}\n";
}

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to