perl hashes learning objectives: 1. to understand the concept of hash as a data structure 2. to...
Post on 20-Dec-2015
216 views
TRANSCRIPT
Perl Hashes
Learning Objectives:1. To understand the concept of Hash as a data
structure
2. To learn the operations of Hash which are available in Perl
3. To understand the usage & application of hash in Perl
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 22
Array of Arrays We can form 2-dimensional array as follows:
@r1 = (1,2,3);@r2 = (4,5,6);@r3 = (7,8,9);# the backslash is to get the reference of a variable# so @m contains 3 pointers to 3 1-D arrays.@m = (\@r1,\@r2,\@r3);print $m[0][1], $m[1][0]; # prints 2,4
Another way is to use the square bracket: @m = ([1,2,3], [4,5,6], [7,8,9]);
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 33
“bill”
“cheap”
What is a Hash? A hash (or associative array) is like an array, where the
index can be any scalar value (not just small non-negative integers).
A hash index is called a key (keys must be unique). The elements of a hash have no fixed order, unlike
arrays. The elements of a hash are like filing cards, where the top
half of the card has the key, and the bottom half has the value.
The keys are used to lookup the values.
16
2046.1
“0 C”
“32 F”
keys:
values:
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 44
Hash Variables (1)
Hash variable names begin with the percent sign (%) followed by the usual variable name.
There is no relationship between $bill, @bill, and %bill, Perl considers them to be separate variables.
Each element of a hash is a separate scalar variable, accessed by the key.
Elements of the hash %bill, are referenced with $bill{$key}, where $key is any scalar expression.
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 55
Hash Variables (2) As with arrays, you create new hash elements:
$bill{"Gates"} = "cheap";$bill{"Clinton"} = "busy";$bill{234.5} = 456.7;
Once created, you can access hash values similar to indexing arrays:
print "Bill Gates is ", $bill{"Gates"}, "\n"; $n = "Clinton";print "Bill $n is $bill{$n}\n";
$n = 234.5;print "Bill $n is $bill{$n}\n";
Output:Bill Gates is cheap Bill Clinton is busyBill 234.5 is 456.7
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 66
Hash Variables (3) Once created, you can change hash values if needed:
$bill{234.5} = 456.7;...$bill{234.5} += 3; # makes it 459.7
Referencing a hash element that does not exist returns the undef value.
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 77
List Representation of a Hash You can access the hash as a whole if you need to initialize it or
to copy it. The hash unwinds as a list. Each pair in the list represents the
key and its value.$bill{"Gates"} = "cheap";$bill{"Clinton"} = "busy";$bill{234.5} = 456.7;@billarray = %bill; # @billarray: qw(Gates cheap Clinton busy 234.5 456.7)%a = @billarray; # create %a like %bill%a = %bill; # faster way to do the same%b = qw(Gates cheap Clinton busy 234.5 456.7);# initialize %b like %bill from list values
The order of the key-value pairs is random in the list representation and cannot be controlled. (Don’t rely on the ordering.)
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 88
Hash “reverse” You can construct a hash with keys and values swapped using
the reverse function:%aback = reverse %a;
If %a has two identical values, those will end up as a single element in %aback (reverse is best used on hashes with unique keys and values).
$ cat reverse1#!/usr/local/bin/perl5 -w$b{"Gates"} = "Bill";$b{"Clinton"} = "Bill";%revb = reverse %b;# print out revb key and value... $ reverse1Bill Gates$
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 99
Retrieving “keys” in a Hash (1) The keys(%hashname) function returns a list of all the keys
currently in the hash.
$bill{"Gates"} = "cheap";$bill{"Clinton"} = "busy";$bill{234.5} = 456.7;@list = keys(%bill); # @list gets qw(Gates Clinton 234.5) in some random order
If there are no elements in the hash, then keys() returns an empty list.
As with other Perl functions, the parentheses are optional: @list = keys %bill;
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 1010
The keys function is often used in foreach loops to print or access the elements one-by-one:
$ cat key#!/usr/local/bin/perl5 -w$bill{"Gates"} = "cheap";$bill{"Clinton"} = "busy";$bill{234.5} = 456.7;foreach $k (sort(keys(%bill))){
print "At $k we have $bill{$k}\n";}$ keyAt 234.5 we have 456.7At Clinton we have busyAt Gates we have cheap$
Retrieving “keys” in a Hash (2)
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 1111
Printing Hashes
You cannot print the entire hash like you can print arrays:
$ cat prhash#!/usr/local/bin/perl5 -w$bill{"Gates"} = "cheap";$bill{"Clinton"} = "busy";$bill{234.5} = 456.7;print "Bill hash: %bill\n";$ prhashBill hash: %bill$
Most Perl programmers use a foreach loop to print hashes (as in the previous slide).
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 1212
“keys” again In a scalar context, keys returns the number of elements in
the hash:
$ cat key1#!/usr/local/bin/perl5 -w$n = keys(%bill);if($n==0){
print "Bill is empty\n";exit;
}print "Bill has $n elements\n";$ key1Bill is empty$
exit is like the C++ exit() function, and ends the program immediately.
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 1313
Retrieving “values” in a hash The values(%hashname) function returns a list of all
the values currently in the hash. The values are in exactly the same order as the keys returned
by keys(%hashname).$ cat value#!/usr/local/bin/perl5 -w$bill{"Gates"} = "cheap";$bill{"Clinton"} = "busy";$bill{234.5} = 456.7;@klist = keys(%bill); @vlist = values(%bill); print "@klist\n"; print "@vlist\n"; $ value234.5 Gates Clinton456.7 cheap busy$
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 1414
each Another way to print a hash is with the each function. each returns a key-value pair as a two-element list. Each time each is called it returns the next key-value pair until
all the elements have been accessed. When no more pairs, each returns an empty list.
$ cat each#!/usr/local/bin/perl5 -w$bill{"Gates"} = "cheap";$bill{"Clinton"} = "busy";$bill{234.5} = 456.7;while(($k,$v) = each(%bill)){
print "At $k we have $v\n";}$ eachAt 234.5 we have 456.7At Gates we have cheapAt Clinton we have busy$
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 1515
“delete” a Hash element with a key How to remove hash elements?
Answer: Use the delete function. The argument is the keyed reference to be deleted:
$ cat delete1#!/usr/local/bin/perl5 -w$bill{"Gates"} = "cheap";$bill{"Clinton"} = "busy";$bill{234.5} = 456.7;delete $bill{"Gates"}; while(($k,$v) = each(%bill)){
print "At $k we have $v\n";}$ delete1At 234.5 we have 456.7At Clinton we have busy$
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 1616
Hash Slices (1) Like an array, a hash can be sliced to access a collection of
elements. We can use a hash slice to compact initialization.
For example:$b{"Gates"} = "cheap";$b{"Clinton"} = "busy";$b{234} = 45;
can be shortened to:($b{"Gates"},$b{"Clinton"},$b{234}) = qw(cheap busy 45);
can be hash sliced as:@b{"Gates","Clinton",234} = qw(cheap busy 45);
(Note that it is @b, not %b.) Another example:
@b{"A" .. "Z"} = (1 .. 26);
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 1717
Hash Slices (2) We can also use a hash slice with variable interpolation :
$ cat hslice#!/usr/local/bin/perl5 -w@b{"Gates","Clinton",234} = qw(cheap busy 45);@k = qw(Gates Clinton);print "The values are: @b{@k}\n";$ hsliceThe values are: cheap busy$
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 1818
Hash Slices - Merging Hashes (1) Hash slices can also be used to merge hashes. In the following example, if there are duplicate keys, the
values overwritten by the %small hash:$ cat merge#!/usr/local/bin/perl5 -w@big{"Gates","Clinton",234} = qw(cheap busy
45);@small{"Horner",234} = qw(111 67);@big{keys %small} = values %small;while(($k,$v) = each(%big)){
print "At $k we have $v\n";}$ mergeAt 234 we have 67At Gates we have cheapAt Horner we have 111At Clinton we have busy$
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 1919
Hash Slices - Merging Hashes (2) A simpler (though slower) way to merge hashes is:
$ cat merge1#!/usr/local/bin/perl5 -w@big{"Gates","Clinton",234} = qw(cheap busy 45);@small{"Horner",234} = qw(111 67);%big = (%big, %small);while(($k,$v) = each(%big)){
print "At $k we have $v\n";}$ merge1At 234 we have 67At Gates we have cheapAt Horner we have 111At Clinton we have busy$
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 2020
Command line & Environment (1) The name of your Perl script is $0 The array for command line parameter is @ARGV The process ID of your Perl script is $$ Last shell execution status: $?
(backtick ` ` command, or system operator) The hash containing your current environment: %ENV
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 2121
Command line & Environment (2)$ cat p1#!/usr/local/bin/perl5 -w$argc = @ARGV;print "parameter count $argc for $0 (PID: $$)\n";print "parmamters: $ARGV[0] $ARGV[1]\n";# put both input and error to /dev/null which means # # don’t print anything. 2>&1 is a unix command for # grouping both standard output and error together, and# put the result into standard output.system "cat non_existing_file > /dev/null 2>&1";print "Status of last command: $? \n";system "cd";print "Status of last command: $? \n";print "You are $ENV{USER} \n";$ p1 a bparameter count 2 for p1 (PID: 20489)parmamters: a bStatus of last command: 512Status of last command: 0You are kwchiu
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 2222
More About Hashes
Another way to initialize hashes:$ cat morehash#!/usr/local/bin/perl5 -w%bill = ( "Gates" => "cheap", "Clinton" => "busy");print "Hello $bill{'Gates'} Bill!\n";$ morehashHello cheap Bill!
You may use single quotes for specifying a key (more convenient inside double quotes).
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 2323
Use of Hash Simple hash as simple relations:
$Name{94001} = "Peter";$Name{94002} = "John";
Simple hash as records:
$John{"studno"} = 94002;$John{"CGA"} = 9.1;$John{"SGA"} = 8.7;...
Hash of hashes: (database) tables
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 2424
Hash of Hashes (1)
Student#
(key)
Attributes
Name CGA Grades
94001 John 9.1 comp111 => A
comp211 => B+
…
94002 Peter 8.5 …
…
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 2525
Hash of Hashes (2) Idea: hash element is a hash pointer
$ cat hashofhash $student{94001}{'name'} = "John";
$student{94001}{'CGA'} = 9.1; print $student{94001}{'name'}; $student{94002} = {"name" => "Peter", "CGA" => 8.5}; foreach $s (keys(%student)) { print "Student $s: ";
print "Name = $student{$s}{'name'}; "; print "CGA = $student{$s}{'CGA'}\n"; }
$ hashofhash John Student 94001: Name = John; CGA = 9.1 Student 94002: Name = Peter; CGA = 8.5
Note { } for creating an anonymous hash instead of ();
$student{94002} now contains a pointer to that hash
Note { } for creating an anonymous hash instead of ();
$student{94002} now contains a pointer to that hash
COMP111COMP111Lecture 13 / Slide Lecture 13 / Slide 2626
Hash of Hashes of Hashes We can form complicated nested data structures with
repeated levels of hashes:$ cat hash3#!/usr/local/bin/perl5 -w$$student{94001}{'grade'}= {"comp111"=>'A',"comp211"=>'B+'};
print $student{94001}{'grade'}{'comp111'};$p = $student{94001}{'grade'}; # $p is a ptrforeach $c (keys(%$p)) { # %$p - the hash pointed by p print "$c $$p{$c}\n";} # $$p{...} - an element of the hash pointed by p
$ hash3comp111 Acomp211 B+