Hello, I'm doing some word counts in Perl and have a problem with the following one. I want to use two subroutines count and show and do a word count on two lines of an array at the same time

I've got two problems with it.
1) when using print at the end of the loop in the count subroutine, I get
1 just
1 trying
1 figure
1 this
1 out
1 cant
2 figure
1 how

but I think, I should get
1 just
1 trying
1 this
1 out
1 cant
2 figure
1 how

in some tries only, one of the two lines is counted when changing the curly brackets.

so, 1) how to get the correct count?
and 2) how to store the result to show it with the show subroutine?

Thanks for your help

# word count perl

my @chains = (
    "just trying to figure this out,",
    "cant figure how to do it…",
);

my %frequence = count( 3, @chains );
show( %frequence);


sub count {

        die "2 arguments needed"
            if @_ <2;

        my $n = shift @_;

        # foreach and split
        foreach my $chain (@chains) {
        my @array = split(/[^a-zA-Zàâäéèêëîïôöùûüç]+/, $chain);

        # grep
        @long_chains = grep { length $_ >= $n } @array;

        # frequencies
        foreach my $word ( @long_chains ) {
            $frequence{$word}++;
            print "$frequence{$word} $word\n";
        }
    }   
}


sub show {

            # hash
        foreach my $word ( sort keys %frequence ) { 
            print "$frequence{$word} $word\n";
        }
}

Edited 3 Years Ago by pritaeas: Moved.

Hi rogerg,
This problem could be easily solved using map and grep in Perl like so:

use warnings;
use strict;

my $splitter = qr/[^a-zA-Zàâäéèêëîïôöùûüç]/;    # split on the following
my %word_freq;                                  ## hash variable

my @chains =
  ( "just trying to figure this out,", "cant figure how to do it…", );

map { $word_freq{$_}++ }    ## get the number of occurrence of such words
  grep { length $_ >= 3 }  ## get only words, which length is more or equal to 3
  map { split /$splitter/, $_ } @chains;    ## split on splitter for each word

print "Freq  Word\n";                       ## print title
print $word_freq{$_}, "  ", $_, $/ for sort keys %word_freq; ## print words and freq.

Output

Freq  Word
1     cant
2     figure
1     how
1     just
1     out
1     this
1     trying

Edited 3 Years Ago by 2teez

The initial solution, I posted is a lot better. But on a second thought, in case you really want to make your soubroutine script work.
Here are some suggestions and a re-construct of your program that works.

  1. using pargma "warnings" and "strict", it shows, variable @long_chains was not declared.

  2. Also the parameters, passed to the subroutine where not used except for 3 in the count
    subroutine. Other variable used in the subroutine were global variable.

  3. Since, those variables were passed into the subroutine it's a lot better to use them.
    In the subroutine, these variable can be accessed from @_.

  4. Always pass variable (parameters) to a subroutine, using scalar or refenence of the
    variable, which is a type of scalar variable.

    #!/usr/bin/perl
    use warnings;
    use strict;
    
    # word count perl
    
    my @chains =
      ( "just trying to figure this out,", "cant figure how to do it…", );
    
    my %frequence = count( 3, \@chains );
    show( \%frequence );
    
    sub count {
        die "2 arguments needed" if @_ < 2;
    
        my ( $counter, $chains_of_words ) = @_;
        my @array;
        my %word_frequence;
    
        # foreach and split
        foreach my $chain (@$chains_of_words) {
            push @array, split( /[^a-zA-Zàâäéèêëîïôöùûüç]+/, $chain );
        }
    
        # grep
        my @long_chains = grep { length $_ >= $counter } @array;
    
        # frequencies
        foreach my $word (@long_chains) {
            $word_frequence{$word}++;
        }
        return %word_frequence;
    }
    
    sub show {
    
        # hash ref
        my $tell_frequence = shift;
        foreach my $word ( sort keys %{$tell_frequence} ) {
            print $tell_frequence->{$word}, ' ', $word, $/;
        }
    }
    

Edited 3 Years Ago by 2teez

This question has already been answered. Start a new discussion instead.