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

Oh wise ones, Lets suppose we have a table consisting of non unique rows which i want to collapse and sum up:
string1 10 string2 30 string1 0 string4 39 string9 345
etc. I usually use hashes to keep count with a loop:
my $rh_count = { } ; if ( exists $rh_count->{$string} ) { $rh_count->{$string}++ ; #increment } else { $rh_count->{$string}=1 ; #set to one }
What i am looking for, is there a more 'elegant' way of doing this. I know this is a minor detail but I was wondering if there is any other way of doing so. Consider the number of different strings not to be known in advance so pre-declaring the hash with the elements inside just to increment them would not work. Bless you

Replies are listed 'Best First'.
Re: using hashes to count
by moritz (Cardinal) on Jun 14, 2007 at 22:41 UTC
    You don't need that exists-clause:

    my %rh_count; $rh_count{$string}++;
    is just fine.

    But you are not summing the values up, you are merely counting them - is that what you want?

    (Update: corrected spelling)

Re: using hashes to count
by FunkyMonk (Bishop) on Jun 14, 2007 at 22:45 UTC
    If you really want to sum them, what about

    my $rh_count = { } ; while ( <DATA> ) { my ( $string, $count ) = split; $rh_count->{$string} += $count; } print "$_: $rh_count->{$_}\n" for keys %$rh_count; __DATA__ string1 10 string2 30 string1 0 string4 39 string9 345

Re: using hashes to count
by ikegami (Patriarch) on Jun 14, 2007 at 22:48 UTC
    To continue from where mortiz left off, summing up the values is easy too.
    my %rh_count; $rh_count{$string} += $value;
      Thank you both of your replies. Yes i am just counting up the occurrences of the strings. What i am worried is, without the 'exists' check, $rh_count->{$keyword}++ would give a warning since it would be undef (provided that it wouldnt have been used before)

        Usual way:

        my @strings = qw/ a a b c a b c d e a b c a b c d /; my %count; foreach ( @strings ) { $count{$_} ||= 0; $count{$_}++; } # Then, if you want to sort the results by value: foreach ( sort { $count{$a} <=> $count{$b} } keys %count ) { print "$_ => $count{$_}\n"; }