Perl Hashes Learning Objectives 1 2 3 To
Perl Hashes Learning Objectives: 1. 2. 3. To understand the concept of Hash as a data structure To learn the operations of Hash which are available in Perl To understand the usage & application of hash in Perl
COMP 111 Lecture 13 / Slide 2 Array of Arrays l We can form 2 -dimensional array as follows: @r 1 = (1, 2, 3); @r 2 = (4, 5, 6); @r 3 = (7, 8, 9); # the backslash is to get the reference of a variable # so @m contains 3 pointers to 3 1 -D arrays. @m = (@r 1, @r 2, @r 3); print $m[0][1], $m[1][0]; # prints 2, 4 l Another way is to use the square bracket: @m = ([1, 2, 3], [4, 5, 6], [7, 8, 9]);
COMP 111 Lecture 13 / Slide 3 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. keys: values: “bill” 16 “ 0 C” “cheap” 2046. 1 “ 32 F”
COMP 111 Lecture 13 / Slide 4 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.
COMP 111 Lecture 13 / Slide 5 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 busy Bill 234. 5 is 456. 7
COMP 111 Lecture 13 / Slide 6 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.
COMP 111 Lecture 13 / Slide 7 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. )
COMP 111 Lecture 13 / Slide 8 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 reverse 1 #!/usr/local/bin/perl 5 -w $b{"Gates"} = "Bill"; $b{"Clinton"} = "Bill"; %revb = reverse %b; # print out revb key and value. . . $ reverse 1 Bill Gates $
COMP 111 Lecture 13 / Slide 9 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;
COMP 111 Lecture 13 / Slide 10 Retrieving “keys” in a Hash (2) § The keys function is often used in foreach loops to print or access the elements one-by-one: $ cat key #!/usr/local/bin/perl 5 -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"; } $ key At 234. 5 we have 456. 7 At Clinton we have busy At Gates we have cheap $
COMP 111 Lecture 13 / Slide 11 Printing Hashes § You cannot print the entire hash like you can print arrays: $ cat prhash #!/usr/local/bin/perl 5 -w $bill{"Gates"} = "cheap"; $bill{"Clinton"} = "busy"; $bill{234. 5} = 456. 7; print "Bill hash: %billn"; $ prhash Bill hash: %bill $ § Most Perl programmers use a foreach loop to print hashes (as in the previous slide).
COMP 111 Lecture 13 / Slide 12 “keys” again § In a scalar context, keys returns the number of elements in the hash: $ cat key 1 #!/usr/local/bin/perl 5 -w $n = keys(%bill); if($n==0){ print "Bill is emptyn"; exit; } print "Bill has $n elementsn"; $ key 1 Bill is empty $ § exit is like the C++ exit() function, and ends the program immediately.
COMP 111 Lecture 13 / Slide 13 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/perl 5 -w $bill{"Gates"} = "cheap"; $bill{"Clinton"} = "busy"; $bill{234. 5} = 456. 7; @klist = keys(%bill); @vlist = values(%bill); print "@klistn"; print "@vlistn"; $ value 234. 5 Gates Clinton 456. 7 cheap busy $
COMP 111 Lecture 13 / Slide 14 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/perl 5 -w $bill{"Gates"} = "cheap"; $bill{"Clinton"} = "busy"; $bill{234. 5} = 456. 7; while(($k, $v) = each(%bill)){ print "At $k we have $vn"; } $ each At 234. 5 we have 456. 7 At Gates we have cheap At Clinton we have busy $
COMP 111 Lecture 13 / Slide 15 “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 delete 1 #!/usr/local/bin/perl 5 -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 $vn"; } $ delete 1 At 234. 5 we have 456. 7 At Clinton we have busy $
COMP 111 Lecture 13 / Slide 16 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);
COMP 111 Lecture 13 / Slide 17 Hash Slices (2) § We can also use a hash slice with variable interpolation : $ cat hslice #!/usr/local/bin/perl 5 -w @b{"Gates", "Clinton", 234} = qw(cheap busy 45); @k = qw(Gates Clinton); print "The values are: @b{@k}n"; $ hslice The values are: cheap busy $
COMP 111 Lecture 13 / Slide 18 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/perl 5 -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 $vn"; } $ merge At 234 we have 67 At Gates we have cheap At Horner we have 111 At Clinton we have busy $
COMP 111 Lecture 13 / Slide 19 Hash Slices - Merging Hashes (2) § A simpler (though slower) way to merge hashes is: $ cat merge 1 #!/usr/local/bin/perl 5 -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 $vn"; } $ merge 1 At 234 we have 67 At Gates we have cheap At Horner we have 111 At Clinton we have busy $
COMP 111 Lecture 13 / Slide 20 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
COMP 111 Lecture 13 / Slide 21 Command line & Environment (2) $ cat p 1 #!/usr/local/bin/perl 5 -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"; $ p 1 a b parameter count 2 for p 1 (PID: 20489) parmamters: a b Status of last command: 512 Status of last command: 0 You are kwchiu
COMP 111 Lecture 13 / Slide 22 More About Hashes § Another way to initialize hashes: $ cat morehash #!/usr/local/bin/perl 5 -w %bill = ( "Gates" => "cheap", "Clinton" => "busy"); print "Hello $bill{'Gates'} Bill!n"; $ morehash Hello cheap Bill! § You may use single quotes for specifying a key (more convenient inside double quotes).
COMP 111 Lecture 13 / Slide 23 Use of Hash l Simple hash as simple relations: $Name{94001} = "Peter"; $Name{94002} = "John"; l Simple hash as records: $John{"studno"} = 94002; $John{"CGA"} = 9. 1; $John{"SGA"} = 8. 7; . . . l Hash of hashes: (database) tables
COMP 111 Lecture 13 / Slide 24 Hash of Hashes (1) Student# (key) 94001 Name John 94002 Peter … Attributes CGA Grades 9. 1 comp 111 => A comp 211 => B+ … 8. 5 …
COMP 111 Lecture 13 / Slide 25 Hash of Hashes (2) § Idea: hash element is a hash pointer Note { } for creating an anonymous hash instead of (); $student{94002} now contains a pointer to that hash $ 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
COMP 111 Lecture 13 / Slide 26 Hash of Hashes l We can form complicated nested data structures with repeated levels of hashes: $ cat hash 3 #!/usr/local/bin/perl 5 -w$ $student{94001}{'grade'}= {"comp 111"=>'A', "comp 211"=>'B+'}; print $student{94001}{'grade'}{'comp 111'}; $p = $student{94001}{'grade'}; # $p is a ptr foreach $c (keys(%$p)) { # %$p - the hash pointed by p print "$c $$p{$c}n"; } # $$p{. . . } - an element of the hash pointed by p $ hash 3 comp 111 A comp 211 B+
- Slides: 26