140 likes | 290 Views
References and complex data structures. Hash – an associative array. An associative array (or simply – a hash ) is an unordered set of key=>value pairs. Each key is associated with a value. A hash variable name always start with a “ % ”: my %h = ("a"=>5, "bob"=>"zzz", 50=>"Johnny");
E N D
Hash – an associative array An associative array (or simply – a hash) is an unordered set of key=>value pairs. Each key is associated with a value. A hash variable name always start with a “%”: my %h = ("a"=>5, "bob"=>"zzz", 50=>"Johnny"); You can access a value by its key: print $h{50}.$h{a}; Johnny5 $h{bob} = "aaa"; (modifying an existing value) $h{555} = "z"; (adding a new key-value pair)
Iterating over hash elements To iterate over the keys in %h foreach $key (keys(%h))... For example: foreach $key (keys(%h)) { print "The key is $key\n"; print "The value is $h{$key}\n"; } The elements are given in an arbitrary order, so if you want a certain order use sort: foreach $key (sort(keys(%h)))...
Why do we need complex data structures? So far, we know two types of data structures: An Array is an ordered list of scalar values:my @names = ("Shmuel", "Moti", "Rahel"); A Hash is an unordered set of pairs of scalar values:my %phoneBook = ("Shmuel"=>5820, "Moti"=>2745); However, in many situations we may need to store more complex data records.For example – how to keep the phone number, address and list of grades for each student in a course? We would like a data record that looks like this: "Shmuel" => (5820, "34 HaShalom St.", (85,91,67)) For this to work we’re going to need references…
$hash{key} $number-3.54 %hash @array => $string"hi\n" => $array[0] => $reference0x225d14 %hash => @array1 => @array2 => @array3 Variable types in PERL Scalar Array Hash
=> @grades => => %phoneBook $phoneBookRef $gradesRef $nameRef $name References A reference to a variable is a scalar value that “points” to the variable: $nameRef = \$name; @grades = (85,91,67); $gradesRef = \@grades; $phoneBookRef = \%phoneBook;
@grades $gradesRef $arrayRef References A reference to a variable is a scalar value that “points” to the variable: $nameRef = \$name; @grades = (85,91,67); $gradesRef = \@grades; $phoneBookRef = \%phoneBook; We can make an anonymous reference without creating a variable with a name: [ITEMS] creates a new, anonymous array and returns a reference to it; {ITEMS} creates a hash: $arrayRef = [85,91,67]; $hashRef = {85=>4,91=>3}; (These are variables with no variable name)
@grades $gradesRef De-referencing $nameRef = \$name; $gradesRef = \@grades; $phoneBookRef = \%phoneBook; print $gradesRef; ARRAY(0x225d14) To access the data from a reference we need to dereference it: print $$nameRef; Yossi print "@$gradesRef"; 85 91 67 $$gradesRef[3] = 100; print "@grades"; 85 91 67 100 $phoneNumber = $$phoneBookRef{"Yossi"}; 100 was added to the original array @grades!
@grades $gradesRef De-referencing $gradesRef = \@grades; $phoneBookRef = \%phoneBook; print "@$gradesRef"; 85 91 67 $$gradesRef[3] = 100; $phoneNumber = $$phoneBookRef{"Yossi"}; The following notation is equivalent, and sometimes it is more readable: $gradesRef->[3] = 100; $phoneNumber = $phoneBookRef->{"Yossi"};
%students => => => References allow complex structures Because a reference is a scalar value, we can store a reference to an array\hash in as an element in another array\hash: @grades = (85,91,67);%students = (Yossi => \@grades);$students{Yossi} = \@grades; $students{Shmuel} = [83,76]; Now the key “Yossi” is paired to a reference value: print $students{Yossi}; ARRAY(0x22e714)print "@{$students{Yossi}}"; 85 91 67print ${$students{Yossi}}[1]; 91print $students{Yossi}->[1]; 91 This form is more readable, we strongly recommend it… %studentsNAME => [GRADES]
%students => => => => => => => => => => => => References allow complex structures Now we can do it: “how to keep the phone number, address and list of grades for each student in a course?” $students{Yossi} = {phone=>3744, address=>"34 HaShalom St.", grades=>[93,72,87]};$students{Rahel} = {phone=>5732, address=>"5 Bazel St.", grades=>[91,86,88]}; %studentsNAME =>{phone => PHONE address => ADDRESS grades => [GRADES]}
%students => => => => => => => => => => => => References allow complex structures Now we can do it: “how to keep the phone number, address and list of grades for each student in a course?” $students{Yossi} = {phone=>3744, address=>"34 HaShalom St.", grades=>[93,72,87]}; print $students{Yossi}->{grades}->[2];87 It is more convenient to use a shorthand notation:print $students{Yossi}{grades}[2] But remember that there are references in there! %studentsNAME =>{phone => PHONE address => ADDRESS grades => [GRADES]}
%students => => => => => => => => => => => => References allow complex structures The following code is an example of iterating over two levels of the structure –The top hash (each student) and the internal arrays (lists of grades): foreach my $name (keys(%students)) { foreach my $grade (@{$students{$name}->{"grades"}}) { print $grade; }} %studentsNAME =>{phone => PHONE address => ADDRESS grades => [GRADES]}
3 6 7 5 8 4 9 2 1 Two dimensional arrays Now we can also create a 2-dimensional array (a table or a matrix): @table = ([1,2,3],[4,5,6],[7,8,9]); print $table[1]->[0]; 4 Or: print $table[1][0]; 4 @table