Talk: Arrays perl

From Teknologisk videncenter
Jump to: navigation, search

Hash of arrays

Another problem we can run into is to have a hash each element of which is an array. In the other words, we would like to associate not just one scalar variable with a key ford, but a whole list of scalar values. The idea of the solution is exactly the same as in the previous section. Instead of keeping scalar values in our hash we will keep pointers to an array.

For example, let we have a file like this:

Bob: 89 76 89 90 100 101
Bill: 100 89 76 80 34 0
Sam: 102 99 87 78 90 69

For each student mentioned in the file we would like to keep her or his grades. To do that we will write the following code:

%grades = ();    # create an empty hash
while( <> ){
   chomp;
   ($name, $grds) = split(/:\s*/, $_);
   $grades{$name} = [ split(/\s+/, $grds) ];
}

for ( keys(%grades) ){
   printf "%8s : %.2f\n", $_, avg( @{$grades{$_}} );
}

sub avg
{
  my @arr = @_;
  my $sum = 0;
  my $count = $#arr + 1;
  for(my $i=0;$i<$count;$i++){
     $sum += $arr[$i];
  }
  $sum/$count;
}

The very first loop just reads the file line by line and splits the line into name and grades, then it uses split function again to get an array of grades, then in the assignment $grades{$name} = [ split(/\s+/, $grds) ]; we initialize an element of the has with the key $name and the value is a pointer to an anonymous array that contains all the grades for the student. To create a pointer we use square brackets around the functions split. In the second loop we call function avg to compute the average grade for each student. Please notice that we use @ in front of the hash element to specify that we pass an array not a pointer to the function.