Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Help on array element counting

by Anonymous Monk
on Oct 27, 2003 at 19:26 UTC ( #302481=perlquestion: print w/replies, xml ) Need Help??

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

Hey everyone ,

I have a question about arrays in perl for everyone, I am really new to perl and facing a lil road block on an array problem.. below is what my array contains
MANGO
APPLE
GRAPES
MANGO
MANGO
MANGO
MANGO
APPLES
APPLES
BANANA
CORN
APPLES
I want to count the number of occurences of each element in the array and output it on the screen like for example
MANGO => 5
APPLES => 3
like that .. I hope this above example was simple enough and provided the information to you guys , can someone please help me out on this part

Thanks a bunch

edited: Mon Oct 27 20:05:46 2003 by jeffa - removed uneccesary code tags, added p tags

Replies are listed 'Best First'.
Re: Help on array element counting
by Zaxo (Archbishop) on Oct 27, 2003 at 19:36 UTC

    Calling your array @fruits,

    for my $fruit (qw{MANGO APPLES}) { print $fruit, ' => ', scalar( grep { $fruit eq $_ } @fruits), $/; }
    that works because grep in scalar context gives you the count.

    The other and sometimes better way is to count them into a hash,

    my %fruit_count; $fruit_count{$_}++ for @fruits; for (qw{MANGO APPLES}) { print $_, ' => ', $fruit_count{$_}, $/; }
    That is better when @fruits is not being updated and you need counts for many different items.

    After Compline,
    Zaxo

Re: Help on array element counting
by TomDLux (Vicar) on Oct 27, 2003 at 19:31 UTC
    my %fruits; $fruits{$_}++ for ( @fruits ); my ( $fruit, $count ); for ( $fruit, $count ) ( each %fruits ) { print "$fruit => $count\n"; }

    --
    TTTATCGGTCGTTATATAGATGTTTGCA

      if you don't mind can u explain me what is going on here .. i would like to learn it as well so i understand it alot better thanks again
        # Declare a hash named fruits. A hash contains # { key,value } pairs where the key fields are unique. my %fruits; # Get each element in the @fruits array and assign it to #the { key } portion of the hash. Also, increment the #{ value } part of the hash (the value starts with 0). #This will count the number of times the { key } appears in #the array $fruits{$_}++ for ( @fruits ); #Declare variables for { key, value } my ( $fruit, $count ); #Get each { key, value } pair and assign them to #{ fruit, count } for ( $fruit, $count ) ( each %fruits ) { #Print out the number of times the fruit existed. print "$fruit => $count\n"; }

        The idea is to loop through the original array. For each element, either look up or add that element as a key into a hash, and increments that key's value by one. Since Perl's hashes use autovivification, when we try to look up a non-existing key in a hash, that key will be added.

        $hash{$_}++ for @array;
        is a very common Perl idiom. If we are processing the element 'APPLE' and it is not in the hash, a new key will be added to the hash, and that key's value (currently undef) will be incremented by 1 ... yielding 1. Later, if we encounter 'APPLE' again, when we try to look up 'APPLE' it exists this time and the value returned is 1. Add 1 to that and now we have 2 apples.

        Remember, Data::Dumper is your friend! Try this out:
        use strict; use warnings; use Data::Dumper; my @fruit = qw( MANGO APPLE GRAPES MANGO MANGO MANGO MANGO APPLES APPLES BANANA CORN APPLES ); my %fruit; $fruit{$_}++ for @fruit; print Dumper \@fruit; print Dumper \%fruit;

        jeffa

        L-LL-L--L-LL-L--L-LL-L--
        -R--R-RR-R--R-RR-R--R-RR
        B--B--B--B--B--B--B--B--
        H---H---H---H---H---H---
        (the triplet paradiddle with high-hat)
        
Re: Help on array element counting
by Limbic~Region (Chancellor) on Oct 27, 2003 at 19:34 UTC
    Anonymous Monk,
    Depending on if the output order is important, only use one of the two print methods shown below.
    #!/usr/bin/perl -w use strict; my @array = qw( mango apples grapes mango mango mango mango apples apples banana corn apples ); my %count; $count{$_}++ for @array; ### Output order not important ### print "$_ => $count{$_}\n" for keys %count; ### Output order is important ### my %seen; for (@array) { next if $seen{$_}; print "$_ => $count{$_}\n"; $seen{$_} = 1; }
    Cheers - L~R
Re: Help on array element counting
by ChrisR (Hermit) on Oct 27, 2003 at 19:36 UTC
    Here is a simple yet explanatory (I hope) way of doing it:
    #!/usr/bin/perl -w use strict; use warnings; use diagnostics; my @array = qw(MANGO APPLE GRAPES MANGO MANGO MANGO MANGO APPLES APPLE +S BANANA CORN APPLES); my %hash; foreach (@array) { $hash{$_}++; } for my $key(keys %hash) { print "$key => $hash{$key}\n"; }
Re: Help on array element counting
by monktim (Friar) on Oct 27, 2003 at 19:37 UTC
    use strict; my @array = <DATA>; chomp @array; my %cnt; $cnt{$_}++ foreach (@array); print "$_ => $cnt{$_}\n" foreach (keys %cnt); __DATA__ MANGO APPLE GRAPES MANGO MANGO MANGO MANGO APPLES APPLES BANANA CORN APPLES
Re: Help on array element counting
by Roger (Parson) on Oct 27, 2003 at 23:14 UTC
    Nothing too fancy, use map to replace for, just to demonstrate the use of map since this is your learning exercise. I also use the Data::Dumper module to investigate my data structure, which can be quite handy.
    use Data::Dumper; @fruits = qw/ MANGO APPLE GRAPES MANGO MANGO MANGO MANGO APPLES APPLES BANANA CORN APPLES /; map { $count{$_}++ } @fruits; print Dumper(\%count);
    And the output is -
    $VAR1 = { 'GRAPES' => '1', 'CORN' => '1', 'APPLES' => '3', 'APPLE' => '1', 'BANANA' => '1', 'MANGO' => '5' };
      Also to illustrate point of 'sort' with hashes, I'd add to this a little. Sorting either by count
      @fruits = qw/ MANGO APPLE GRAPES MANGO MANGO MANGO MANGO APPLES APPLES BANANA CORN APPLES /; map { $count{$_}++ } @fruits; foreach (sort {$count{$a} <=> $count{$b}} keys %count) { print "$_ => $count{$_}\n"; }
      Or to sort them by fruits (changing the sort)
      foreach (sort {lc($a) cmp lc($b)} keys %count) { print "$_ => $count{$_}\n"; }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://302481]
Approved by kvale
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (3)
As of 2022-09-25 04:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    I prefer my indexes to start at:




    Results (116 votes). Check out past polls.

    Notices?