Home arrow Perl Programming arrow Page 4 - Hash Mania With Perl

Subbing Out Sorting&toc - Perl

Perl hashes are extremely useful data structures that allow us to associate one piece of data to another. In this article, Jasmine will review hashes and introduce some of their more advanced uses.

TABLE OF CONTENTS:
  1. Hash Mania With Perl
  2. Assigning Key/Value Pairs
  3. Sorting Hashes
  4. Subbing Out Sorting
By: D. Jasmine Merced
Rating: starstarstarstarstar / 44
April 15, 2004

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement
Think it will introduce too many typos to remember the construct for alphabetical sorting? Then "sub" it! Let's say you use sorting very frequently in your programming and find it cumbersome to type in the above operations each time.

Let's handle this by example:

 foreach my $key (sort ascend_alpha keys %hash){ 
print 
"$key = $hash{$key}
"




You can easily see that the lc($a) cmp lc($b) has been replaced by a subroutine call. Now, let's consider the following:

 sub ascend_num {$a <=> $b
sub descend_num 
{$b <=> $a
sub ascend_alpha 
{lc($acmp lc($b)} 
sub descend_alpha 
{lc($bcmp lc($a)} 
sub ascend_alphanum 
{$a <=> $b || lc($acmp lc($b)} 
sub descend_alphanum 
{$b <=> $a || lc($bcmp lc($a)} 



The ascend_alphanum and descend_alphanum routines sort both alphabetically and numerically, so if you added "5 Spice Seasoning", "1 Star Flour", and "911 Hot Sauce" to %hash, it will sort the numbers numerically in addition to letters alphabetically.

Apples = 1
apples = 4
artichokes = 3
Beets = 9
canadian = 9
5 Spice Seasoning = 1
10 Star Flour = 1
911 Hot Sauce = 1

Working with Hash References
Have a hash reference and don't want to duplicate the subroutines to deal with them? It's easy... just pass the dereferenced keys to the sort routines:

 $hashref = %hash

foreach my $key 
(sort ascend_alpha keys %{$hashref}){ 
print 
"$key = $hashref->{$key}
"




Notice the hash deference %{$hashref} and the arrow dereferencer for the value $hashref->{$key}.

Sorting by Hash Values
What if you wanted to sort the values instead of the keys? Consider the following:

 foreach my $key (sort {$hash{$a} <=> $hash{$b}} keys %hash){ 
print 
"$key = $hash{$key}
"




This will print out:

Apples = 1
5 Spice Seasoning = 1
10 Star Flour = 1
APples = 2
artichokes = 3
apples = 4
911 Hot Sauce = 4
canadian = 9
Beets = 9

But let's say you also had text values -- let's change $hash{'Beets'} to "cans: 4 - 8.oz." and $hash{'Apples'} to "Delicious Red - 4 medium sized". You can have the hash sorted numerically and alphabetically by using the following:

 foreach my $key (sort {$hash{$a} <=> $hash{$b} || $hash{$acmp $hash{$b}} keys %hash){ 
print 
"$key = $hash{$key}
"




This will correctly print out:

Beets = cans: 4 - 8.oz.
Apples = Delicious Red - 4 medium sized
5 Spice Seasoning = 1
10 Star Flour = 1
APples = 2
artichokes = 3
apples = 4
911 Hot Sauce = 4
canadian = 9

Multidimensional Hashes
Using key/value pairs is great, but what if you wanted to associate more than one value to a key? Using a slightly different construct, you can essentially use an array as a key's value:

 %hash = ( 
Apples 
=> [4"Delicious red""medium"], 
"Canadian Bacon" => [1"package""1/2 pound"], 
artichokes 
=> [3"cans""8.oz."], 
Beets 
=> [4"cans""8.oz."], 
"5 Spice Seasoning" => [1"bottle""3 oz."], 
"10 Star Flour" => [1"package""16 oz."], 
"911 Hot Sauce" => [1"bottle""8 oz."], 
); 



Now, to extract the values, you can treat them as an array of the hash:

 print $hash{"Canadian Bacon"}[1]; 



...will print package, because package is the second element of Canadian Bacon's "array". You can also add an predefined array to a hash value:

 @garlicstuff = (4"cloves""medium"); 
$hash
{"Garlic"} = [@garlicstuff]; 
print $hash
{"Garlic"}[1]; # prints cloves 



But what if @garlicstuff had more elements than others? Let's say that @garlicstuff is

 @garlicstuff = (4"cloves""medium""chopped"); 



instead? How do we print out all values for a key if one key can have 3 values, and another has 4 (or more) values?

 foreach my $key (sort ascend_alpha keys %hash){ 
print 
"$key
"

foreach my $val 
(@{$hash{$key}}){ 
print 
"    $val
"


print 
"
"




Because a multidimensional array's values are essentially arrays, a key's group of values can be dereferenced by using @{$hash{$key}}. The above code prints:

10 Star Flour:
1
package
16 oz.

5 Spice Seasoning:
1
bottle
3 oz.

911 Hot Sauce:
1
bottle
8 oz.

Apples:
4
Delicious red
medium

artichokes:
3
cans
8.oz.

Beets:
4
cans
8.oz.

Canadian Bacon:
1
package
1/2 pound

Garlic:
4
cloves
medium
chopped

 
 
>>> More Perl Programming Articles          >>> More By D. Jasmine Merced
 

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort
   

PERL PROGRAMMING ARTICLES

- Perl Turns 25
- Lists and Arguments in Perl
- Variables and Arguments in Perl
- Understanding Scope and Packages in Perl
- Arguments and Return Values in Perl
- Invoking Perl Subroutines and Functions
- Subroutines and Functions in Perl
- Perl Basics: Writing and Debugging Programs
- Structure and Statements in Perl
- First Steps in Perl
- Completing Regular Expression Basics
- Modifiers, Boundaries, and Regular Expressio...
- Quantifiers and Other Regular Expression Bas...
- Parsing and Regular Expression Basics
- Hash Functions

Developer Shed Affiliates

 


Dev Shed Tutorial Topics: