in reply to perl sort issue while going through article at perl.com

my @popular = (sort { $histogram{$b} <=> $histogram{$a} } @unique)[0. +.2]; print "@popular\n"; __END__ tomato watermelon oranges

Correct - hash keys, sorted descending by value, first three ( values are 4,3,2).

my @popular = (sort { $histogram{$a} <=> $histogram{$b} } @unique)[0. +.2]; print "@popular\n"; __END__ apple oranges watermelon

Also correct - hash keys, sorted ascending by value, first three (values are 1,2,3).

If you iterate over the hash keys and print them out with their value, they will come out in any order. A hash isn't sorted.

--shmem

_($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                              /\_¯/(q    /
----------------------------  \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

Replies are listed 'Best First'.
Re^2: perl sort issue while going through article at perl.com
by convenientstore (Pilgrim) on Oct 22, 2007 at 05:18 UTC
    one more question from same tutorial, can you do below in reference hash?
    my %histogram; $histogram{$_}++ for @list;
    I was trying
    foreach (@data1) { $hist{$_}++ for $_; } my @uni = keys %hist; print "@uni\n";
    but above actually prints out the reference address. I tried few different things but does not print out the actual value.. can someone give me a pointer on this(no pun intended).. thanks. for example like below....
    #!/usr/bin/perl -w use strict; use warnings; use Data::Dumper; my $ref = { a => { A => 1, B => 2, C => 3}, b => { D => 1, E => 2, F => 4}, c => { G => 2, H => 1, I => 2}, }; #print Dumper($ref); my %hist; foreach ($ref) { $hist{$_}++ for $_; } my @uni = keys %hist; print "@uni\n";
      foreach ($ref) { $hist{$_}++ for $_; }

      Your $ref is a hash reference - use keys:

      for ( keys %$ref) { ... }

      Since your data structure is a HoH, inside that loop $_ is, again, a hash reference. Again you need keys.

      $hist{$_}++ for keys %$_;

      But such usage of $_ is a bit obfuscated. Better say

      for my $hashref ( keys %$ref) { $hist{$_}++ for keys %$hashref; }

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
        thank you. I need to go over those HOH tutorial again.. I don't think I have full grasp of it but your solution works for me. thank you again.
        why doesn't below program produce number of keys?
        #!/usr/bin/perl -w use strict; use diagnostics; my $hash = { key1 => 'value1', key2 => 'value2', key3 => 'value3', key1 => 'value3', key1 => 'value33', key1 => 'value3', key2 => 'value3', key2 => 'value3', key4 => 'value3', key4 => '23232', }; #foreach (keys %{$hash}) { # print "$_ => ${$hash}{$_}\n"; #} my %hist; foreach (keys %{$hash}) { $hist{$_}++ for $_; } foreach (keys %hist) { print "$_ , $hist{$_}\n"; } print "size of hash: " , keys(%{$hash}) . "\n"; ././././perl.hash.basic.2 key2 , 1 key1 , 1 key4 , 1 key3 , 1 size of hash: 4
        I am looking to find out how many key2 are in the hash and how many key1 is in the hash and etc.. Below tutorial does not tell you how many of each key exists in the hash
        Now there are two passes over the list, and the situation isn't going +to get any prettier from here. What you want is basically a histogram + of the data, and you can get that with a hash: my %histogram; $histogram{$_}++ for @list; This hash associates each individual item with its count, and it only +traverses the list once. In a recent case, I was looking at a list of tags associated with vari +ous photographs. To lay out the data for display, it was useful to kn +ow how many different tags there are in the list. I could get that si +mply from the number of keys in the histogram: $unique = keys %histogram; I could also delete the duplicates and end up with a list of the uniqu +e tags: @unique = keys %histogram;