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
COMP111 Lecture 13 / Slide 2 Perl Hashes Table of Content What is a Hash ? Hash Variables List Representation of a Hash Hash “reverse” Retrieving “keys” in a Hash Printing Hashes Keys again Retrieving “values” in a Hash each Delete a Hash element with a key Hash Slices Hash Slices – Merging Hashes Command line & Environment More About Hashes Use of Hash Hash of Hashes Hash of Hashes of Hashes Array of Arrays
COMP111 Lecture 13 / Slide 3 “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 “0 C” “32 F” keys: values:
COMP111 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 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.
COMP111 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 is 456.7
COMP111 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 Referencing a hash element that does not exist returns the undef value.
COMP111 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} = = %bill; qw(Gates cheap Clinton busy ) %a # create %a like %bill %a = %bill; # faster way to do the same %b = qw(Gates cheap Clinton busy ); # 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.)
COMP111 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 reverse1 #!/usr/local/bin/perl5 -w $b{"Gates"} = "Bill"; $b{"Clinton"} = "Bill"; %revb = reverse %b; # print out revb key and value... $ reverse1 Bill Gates $
COMP111 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} = = keys(%bill); 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 = keys %bill;
COMP111 Lecture 13 / Slide 10 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"; } $ key At we have At Clinton we have busy At Gates we have cheap $ Retrieving “keys” in a Hash (2)
COMP111 Lecture 13 / Slide 11 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"; $ prhash Bill hash: %bill $ Most Perl programmers use a foreach loop to print hashes (as in the previous slide).
COMP111 Lecture 13 / Slide 12 “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"; $ key1 Bill is empty $ exit is like the C++ exit() function, and ends the program immediately.
COMP111 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/perl5 -w $bill{"Gates"} = "cheap"; $bill{"Clinton"} = "busy"; $bill{234.5} = = = values(%bill); print print $ value Gates Clinton cheap busy $
COMP111 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/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"; } $ each At we have At Gates we have cheap At Clinton we have busy $
COMP111 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 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"; } $ delete1 At we have At Clinton we have busy $
COMP111 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 = qw(cheap busy 45); (Note that it not %b.) Another "Z"} = (1.. 26);
COMP111 Lecture 13 / Slide 17 Hash Slices (2) We can also use a hash slice with variable interpolation : $ cat hslice #!/usr/local/bin/perl5 = qw(cheap busy = qw(Gates Clinton); print "The values are: $ hslice The values are: cheap busy $
COMP111 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/perl5 = qw(cheap busy = qw(111 %small} = values %small; while(($k,$v) = each(%big)){ print "At $k we have $v\n"; } $ merge At 234 we have 67 At Gates we have cheap At Horner we have 111 At Clinton we have busy $
COMP111 Lecture 13 / Slide 19 Hash Slices - Merging Hashes (2) A simpler (though slower) way to merge hashes is: $ cat merge1 #!/usr/local/bin/perl5 = qw(cheap busy = qw(111 67); %big = (%big, %small); while(($k,$v) = each(%big)){ print "At $k we have $v\n"; } $ merge1 At 234 we have 67 At Gates we have cheap At Horner we have 111 At Clinton we have busy $
COMP111 Lecture 13 / Slide 20 Command line & Environment (1) The name of your Perl script is $0 The array for command line parameter The process ID of your Perl script is $PID Last shell execution status: $? (backtick ` ` command, or system operator) The hash containing your current environment: %ENV
COMP111 Lecture 13 / Slide 21 Command line & Environment (2) $ cat p1 #!/usr/local/bin/perl5 -w $argc print "parameter count $argc for $0 (PID: $$)\n"; print "parmamters: $ARGV[0] $ARGV[1]\n"; 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 b parameter count 2 for p1 (PID: 20489) parmamters: a b Status of last command: 512 Status of last command: 0 You are kwchiu
COMP111 Lecture 13 / Slide 22 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"; $ morehash Hello cheap Bill! You may use single quotes for specifying a key (more convenient inside double quotes).
COMP111 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
COMP111 Lecture 13 / Slide 24 Hash of Hashes (1) Student# (key) Attributes NameCGAGrades 94001John9.1comp111 => A comp211 => B+ … 94002Peter8.5 … …
COMP111 Lecture 13 / Slide 25 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
COMP111 Lecture 13 / Slide 26 Hash of Hashes of Hashes l 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 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 $ hash3 comp111 A comp211 B+
COMP111 Lecture 13 / Slide 27 Array of Arrays l We can form 2-dimensional array as = = = (7,8,9); # the backslash is to get the reference of a variable # contains 3 pointers to 3 1-D = print $m[0][1], $m[1][0];# prints 2,4 l Another way is to use the square bracket (address of anonymous = ([1,2,3], [4,5,6], [7,8,9]); l Similarly, we can have hash of arrays and array of hashes, and other nested data structures....