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.
| [reply] [d/l] [select] |
Re: Help on array element counting
by TomDLux (Vicar) on Oct 27, 2003 at 19:31 UTC
|
| [reply] [d/l] |
|
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
| [reply] |
|
# 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";
}
| [reply] [d/l] |
|
|
|
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;
| [reply] [d/l] [select] |
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 | [reply] [d/l] |
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";
}
| [reply] [d/l] |
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
| [reply] [d/l] |
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'
};
| [reply] [d/l] [select] |
|
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";
}
| [reply] [d/l] [select] |