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

If I want to search a hash by strings in an array, and if the string exists in the hash how do I increment the value of the hash. This is the code i have but its not working.
foreach $word (@words){ if($word eq $word_list{$word}){ $word_list{$word}= $word_list{$word} + 1; } else{ $word_list{$word} = 1; } }

Replies are listed 'Best First'.
Re: hard referencing in hashes?!?
by DamnDirtyApe (Curate) on Nov 08, 2002 at 02:28 UTC

    How about something like this:

    #! /usr/bin/perl use strict ; use warnings ; use Data::Dumper ; my @match_arr = qw( count pick words ) ; my %match_hash = map { $_ => 1 } @match_arr ; my %word_count ; while ( <DATA> ) { my @words = split ; for ( @words ) { $word_count{$_}++ if $match_hash{$_} } } print Dumper \%word_count ; exit ; __DATA__ This is my data. I will first count all the words herein, then pick and choose the data I want. I can pick the words using grep.

    _______________
    DamnDirtyApe
    Those who know that they are profound strive for clarity. Those who
    would like to seem profound to the crowd strive for obscurity.
                --Friedrich Nietzsche
      Thanks! but for my assignment i only have to count all the words in a file. Thats why I used hashes....but i found the powerful use of EXISTS :P. Make life so much easier. Now my problem is sorting the results of each word by acending or decending order.

        Look at using a Schwartzian Transform:

        my @sorted = sort { $b->[1] <=> $a->[1] } map { [ $_, $word_count{$_} ] } keys %word_count ;

        _______________
        DamnDirtyApe
        Those who know that they are profound strive for clarity. Those who
        would like to seem profound to the crowd strive for obscurity.
                    --Friedrich Nietzsche
        generally we use sort
Re: hard referencing in hashes?!?
by jdporter (Paladin) on Nov 08, 2002 at 04:07 UTC
    Well, a) you can increment just about anything with the ++ operator.
    And b) there's no need to see whether the element exists in the hash yet, because if you apply the ++ to a non-existent item, it treats it like it had the value of 0.

    So:

    foreach $word ( @words ) { $word_list{$word}++; }
    That should do it. Perl makes the easy things easy!
      map { $word_list{$_}++ } @words;
        $word_list{$_}++ for @words; @sorted = sort keys %word_list;
Re: hard referencing in hashes?!?
by LEFant (Scribe) on Nov 08, 2002 at 03:19 UTC
    If I structure a solution as a c, java, or BASIC programmer might:
    my %word_list = ( bat=> 0, cat=> 0, eat=> 0, fat=> 0 ); my @words = qw( bat bat dat fat eat eat eat fat ); my $word; foreach $word (@words){ if(exists $word_list{$word}){ $word_list{$word}= $word_list{$word} + 1; } else{ $word_list{$word} = 1; } } foreach $word (sort keys %word_list) { print "$word: $word_list{$word}\n"; }
    If I want a perlish solution I would write:
    %word_list = ( bat=> 0, cat=> 0, eat=> 0, fat=> 0 ); my @words = qw( bat bat dat fat eat eat eat fat ); my $word; foreach $word (@words){ $word_list{$word}++; } foreach $word (sort keys %word_list) { print "$word: $word_list{$word}\n"; }
    If don't need a the original word_list for displaying words that were not matched (word count is 0) but want only the counts of the words that occur in @words then an empty %word_list.
    my %word_List = ( );
    Using a hash and increment to count things is a fundamental technique to master early in your perl walk.

    RBL