Title: The Hash Cookbook
1The Hash Cookbook
2- Ingredients
- What goes into a hash
- Basic manipulations
- Recipes
- Test for presence of a value in a list
- Test for uniqueness
- Difference in lists
- Sort in any order
- Use table look-up instead of many if elsif
- call subroutines by reference
3Ingredients
4What is a Hash?
- Not something you smoke
- Not something you eat
- Not
- Key , Value Pairs
- Associative Arrays
- a direct language supported data type
- The third major data type in Perl
- work very similarly to hash tables (named for
hash functions)
5hash
Key1 Value1
Key2 Value2
Key3 Value3
6Initialize (clear, or empty) a hash my hash
() Add a key/value pair to a hash hash key
value Add several key/value pairs to a
hash hash ( key1 gt 'value1', key2 gt
'value2', key3 gt 'value3', ) Delete a
single key/value pair delete hashkey Copy
a hash my hash_copy hash Get each
key foreach key (keys (hash)) print " key
gt hashkey
7Get each value foreach value (values(hash))
print " value \n" Get each key/value
pair while ( my (key, value) each(hash))
print "key gt value\n" Get all of the
values or keys _at_all_keyskeys(hash) _at_all_value
svalues(hash) Get some of the values
(slice) _at_slice_at_hashkey2,key3 _at_slice is
now (value2,value3) Get the size of a hash my
size keys( hash) if a hash value exists, is
defined, or is true if exists hash key if
defined hash key if hash key
8Recipes
These Recipes show where hashes can be used to
solve some common programming challenges.
9Test for presence of a value in a list
green
yellow
blue
red
orange
_at_color_ary
green
1
_at_color_hash
blue
1
yellow
1
1
red
orange
1
10the array way
my _at_color_ary qw(green blue yellow red
orange) my searchshift e.g. red for my
item (_at_color_ary) if (item eq search)
print "Found search\n" exit
11the hash way
my _at_color_ary qw(green blue yellow red
orange) put the array in a hash as keys arrays
can be read into hashes once, and the hash
checked any number of times in the program my
color_hashfor my item (_at_color_ary)
color_hashitem 1 1 or any "true"
value find what we are looking for as the key
of a hash my searchshift if (colorsearch)
print "Found search\n" another way to put
the array in the hash my color_hash map _,
1 _at_color_ary
12Test for uniqueness
_at_list
6
seen
1
2
2
_at_uniq
13Use a hash to record which items have been seen
in a list and how many times my _at_list_at__ my
seen () my _at_uniq () foreach my item
(_at_list) push(_at_uniq, item) unless
seenitem if the item has never been
seen it will be 0 before 1 is added to it and
therefore pushed into the array. The next time it
wont be. return _at_uniq to find the unique
values other ways to do it seen () _at_uniqu
grep ! seen_ _at_list ListMoreUtils
uniq _at_list
14Difference in lists
_at_A
_at_B
1
DOG
seen
1
RAT
1
CAT
1
PIG
_at_aonly
15Find elements in _at_A that aren't in
_at_B \_at_Ashift \_at_Bshift seen () lookup
table of items in _at_B _at_aonly () build hash
table foreach item (_at_B) seenitem 1
Add when not in seen foreach item (_at_A)
push(_at_aonly, item) unless (seenitem) r
eturn _at_aonly
16Sort in any order
_at_unsorted
_at_compar
_at_sorted
17sort in any order, that is not alphabetical, or
numeric my compar ('The_Holy_One' gt 1,
'angel_of_death' gt 2, 'butcher' gt 3, 'ox'gt 4,
'water'gt5, 'fire'gt6, 'stick'gt7, 'dog'gt8,
'cat'gt9, 'kid'gt10) my _at_unsorted _at__ my
_at_sorted sort any_order _at_unsorted return
_at_sorted sort subroutine compares the hash
values sub any_order compara ltgt
comparb
18Improve the logic of your program
Use table look-up instead of many if
elsif example translates numbers from French or
English to digits
_at_words
num_for
num
1984
19the if-else way my (words)_at__ my num for my
words (_at_word) if (word eq zero) num .
0 if (word /(oneunune)/) num .
1 elsif (word /(twodeux)/) num .
2 etc..... elsif (word
/(nineneuf)/) num . 9 return num
20the hash way
my num_for(zero'gt0,one'gt1,'un'gt1,'une'gt1,'
two'gt2, 'deux'gt2,troisgt3,threegt3,quatre
gt4, fourgt4, cinqgt5,fivegt5,
sixgt6,septgt7, sevengt7,huitgt8,
eightgt8,'nine'gt9,'neuf'gt9) my
(words)_at__ my num foreach my
wrd(_at_words) my digitnum_forlc wrd)
if (defined digit) num .digit
return num
21calling subroutines by reference
Use a hash instead of symbolic reference
with a dispatch table you can keep strict
references and can use a different name for the
sub, but must include all of the subs in a hash.
22symbolic reference (name of the subroutine is
itself the reference) my func shift my
argshift no strict 'refs' assuming that
you have use strict func-gt( arg ) if defined
func use strict 'refs' sub jumpprint "jump
arg!\n" sub hop print "hop arg!\n" sub sit
print "sit arg!\n"
23The hash way actual reference (reference is a
pointer to the code)
my subs('j' gt \jump, 'h'gt\hop,'s'gt\sit)
my func shift my argshift subsfunc-gt(
arg) if exists subsfunc sub jumpprint
"jump arg!\n" sub hop print "hop
arg!\n" sub sit print "sit arg!\n"
24- Also
- Change data in files,
- have mapped parameters
- And much more
25References
- Programming Perl (3rd Edition) by Larry Wall,
Tom Christiansen, and Jon Orwant - Perl Cookbook, Second Edition by Tom
Christiansen and Nathan Torkington - Perl Best Practices by Damian Conway
26- http//effectiveperl.blogspot.com/2006/01/idiomati
c-perl-hash-as-set.html - http//www.devshed.com/c/a/Perl/Hash-Mania-With-Pe
rl/ - http//www.cs.mcgill.ca/abatko/computers/programm
ing/perl/howto/hash/ - http//www.perl.com/pub/a/2006/11/02/all-about-has
hes.html - http//www.ebb.org/PickingUpPerl/pickingUpPerl_6.h
tml - http//www.unix.org.ua/orelly/perl/learn/ch05_04.h
tm
27Our Southwestern-inspired Turkey Sweet Potato
Hash is a satisfying and flavorful recipe for
turkey leftovers. 1 1/2 cups roughly chopped
baked sweet potatoes (about 1 1/2 medium
potatoes) 2 1/2 cups shredded cooked turkey 1/4
cup chicken broth 1/2 medium yellow onion, grated
2 cloves garlic, minced 3 tablespoons chopped
fresh coriander , plus leaves for garnish 1/3
cup tofu crumbled 1 large egg white 2 teaspoons
salt Freshly ground black pepper 1 tablespoon
oil, such as soy, peanut, vegetable or corn 2
tablespoons margarine 2 scallions (white and
green), thinly sliced
Turkey Sweet Potato
Hash
28Equipment 10-inch non-stick skillet with
oven-proof handle Preheat the oven to 400 degrees
F. Mash 1 cup of the sweet potatoes in a large
bowl with a fork. Add the remaining 1/2 cup of
sweet potatoes, the turkey, broth, onion, garlic,
coriander, 1/4 cup of the tofu, and the egg
white. Season with the salt and pepper. Stir
briskly to combine. Heat the oil and 1
tablespoon margarine in the skillet over medium
heat. Add the hash and form it into a round cake
the size of the pan with a spatula. Cook, shaking
the skillet occasionally, until the bottom sets,
about 3 minutes. To turn the hash, set a plate
the size of the skillet on top of the pan. Invert
the pan so the hash falls intact onto the plate.
Melt the remaining tablespoon margarine in the
skillet. Slide the hash back into the skillet
cooked-side up. If the hash breaks apart, simply
re-form the cake with the spatula. Cook, shaking
the skillet occasionally, for 2 minutes.
Transfer the skillet to the oven and bake the
hash until firm, about 10 minutes. Carefully,
invert the hash onto a serving plate. Scatter the
scallions, coriander, and the remaining tofu on
the top