Reference Demo. Grep/Map Demo, Too!
#!/usr/bin/perl -w
##################### Elementary Reference Review #######################
##################### Map/Grep Review, Too!! #######################
@L1 = qw(2 4 6 8 10);
@L2 = qw(5 7 4 9 3);
@L3 = dot_product(\@L1, \@L2); # Pass refs. to sub to preserve identity!
print "@L3\n";
sub dot_product
{
my ($r1, $r2) = @_; # Get two list references.
my @result;
return () if @$r1 != @$r2; # Can't do dot product if sizes different!
@result = map { $r1->[$_] * $r2->[$_] } 0..(@$r1 - 1);
return @result;
}
#
%H1 = qw(Bob 4 Mary 8 Carol 10 Willie 2);
%H2 = qw(Joanne 12 Mary 13 Sue 9 Sofie 14 Bob 20);
%H3 = qw(Bill 17 Marge 6 Mary 9 Bob 2);
print join(" ", @{hash_intersections(\%H1, \%H2, \%H3)}),"\n";
sub hash_intersections
{
my (@hrefs) = @_;
my ($key, %keycount);
foreach $key (map {keys %$_} @hrefs)
{
$keycount{$key}++;
}
## Return reference to list of keys whose count == # of hashes.
return [grep {$keycount{$_} == @hrefs} keys %keycount];
}
########################### Output Below ##############################
10 28 24 72 30 # Dot product
Bob Mary # Hash keys which all hashes have in common.
######################## Two-Dimensional Arrays ########################
open(TWO_D, "scores") or die "Cannot open scores file!\n";
push(@scores, [split]) while <TWO_D>; # Push list REFERENCE into @scores.
close TWO_D;
foreach $row (@scores) # Print out the values row by row!!
{
foreach $score (@$row) # Each element of @scores is a list REF!!
{
print "$score "; # Question: Can I do this in ONE loop?
}
print "\n";
}
$colavg = avg_col1(1, @scores); # Average of scores in column 1.
# Zero is the first column.
print "\nAverage of column 1: $colavg\n";
$colavg = avg_col2(1, \@scores);
print "Average of column 1: $colavg\n";
sub avg_col1
{
my ($col, @scores) = @_;
my $sum;
$sum = $num = 0;
foreach $rowref (@scores)
{
$num++;
$sum += $rowref->[$col];
}
return $sum/$num;
}
sub avg_col2
{
my ($col, $scoreref) = @_;
my $sum;
$sum = $num = 0;
foreach $rowref (@$scoreref)
{
$num++;
$sum += $rowref->[$col];
}
return $sum/$num;
}
############################# Program Output ############################
67 87 89 55 76
78 99 87
55 66 77 88 77 66 55
Average of column 1: 84
Average of column 1: 84
#!/usr/bin/perl -w
####################### More Fun With References ##########################
$ref = []; # Reference to an anonymous list.
# Question: How do I use push to add to this list?
push(@$ref, qw(a b c d)); # Did it work?
print "@$ref\n\n"; # Print 1.
@L1 = (1,2,3);
@L2 = qw(Hi Bye Go);
@L3 = qw(Cat Dog);
@LoL = (\@L1, \@L2, \@L3); # List of list references.
foreach $ref (@LoL) # How do I get the element at index 1 of each list?
{
print "$ref->[1] "; # Same as $$ref[1] but -> notation is superior!
} # Print 2.
print "\n";
# Prints 3 and 4.
print "$LoL[0]->[1] $LoL[1]->[1] $LoL[2]->[1]\n"; # Same as loop above!!
print "$LoL[0][1] $LoL[1][1] $LoL[2][1]\n"; # Same as previous statement.
# Adjacent indices need not
# be separated by ->
$ref_of_ref = [\@L1, \@L2, \@L3]; # Reference to list of references!!
# Prints 5 and 6
print "$ref_of_ref->[1]->[1]\n"; # Should be "Bye".
print "$ref_of_ref->[1][1]\n\n"; # The same. Adjacent indices imply
# a -> so it need not be given!
@L4 = qw(foo bar snafu); # How do I push a reference to @L4 onto
# $ref_of_ref??
push(@$ref_of_ref, \@L4); # Did it work?
foreach $ref (@$ref_of_ref)
{
print "@$ref\n"; # Print 7
}
print "\n";
# How about a slice of a list in a 2-D list such as @LoL above?
# Print 8.
print "@{$LoL[1]}[2,1]\n"; # Go Bye is the result. Why? Because
# $LoL[1] is a reference to @L2. We must
# use @ to dereference to get a list because
# a slice of a list is still a list!!
######################### Program Output Below! ##########################
a b c d # Print 1
2 Bye Dog # Print 2
2 Bye Dog # Print 3
2 Bye Dog # Print 4
Bye # Print 5
Bye # Print 6
1 2 3 # Print 7
Hi Bye Go
Cat Dog
foo bar snafu
Go Bye # Print 8