A List of Hashes
February 7, 2000
If you're brain isn't twisted enough yet, let's consider a
list wherein each item is a hash. Who would do such a thing?
Well, maybe a used car dealership for example, and not only
because of its mind-bending qualities. Imagine that we have
a list of "pre-owned" cars for sale. Each car
possesses a number of important sale characteristics such
as its make, model, year, color, mileage, and price. These
properties are ideally suited for a hash of key-value
pairs. So, we can sum up each sale auto as a hash, and we
can compile all of our sale autos into a list.
@carsforsale=({"make"=>"Toyota",
"model"=>"Avalon",
"year"=>"1998",
"color"=>"black",
"mileage"=>"23000",
"price"=>"13500"});
Initially, we've created a list carsforsale with one
item. That one item is a hash, defined within the curly
braces, with all relevent key-value pairs. We can pluck out
any one of these values, such as the make of the first
car on the list (Toyota):
$carsforsale[0]{"make"}
A trade-in arrives on the lot and we're ready to hose it
down and add it to our list of cars for sale. First, we
might create a temporary hash to contain its characteristics,
and then push that hash onto our carsforsale list:
%temp=("make"=>"Nissan",
"model"=>"Maxima",
"year"=>"2000",
"color"=>"green",
"mileage"=>"5520",
"price"=>"18750");
push(@carsforsale,{%temp});
You don't have to use a temporary hash as the middleman,
but it makes the code that much more legible, relatively
speaking. Now, what can we do with a list of hashes such as
this? One idea is to simply print it all out ... that is,
create a catalog of used cars for sale. Leveraging our
knowledge of sorting, we can create output which is sorted
by ascending price. We'll also want to sort the hash keys,
such as "make", "model", "year",
and so forth, otherwise they may appear in a different order
for each car, since hash keys are intrinsically non-ordered.
#Double-sort by price and key
print "\nCars for sale sorted by price:\n";
$count=0;
foreach $saleitem
(sort {$a->{price}<=>$b->{price} } @carsforsale)
{$count++;
print "Sale item $count:\n";
foreach $hash_key (sort keys %{$saleitem})
{print "\t$hash_key: $saleitem->{$hash_key}\n"}
}
The outer foreach loop iterates over each hash
(sale item) in the carsforsale list. These items are
sorted using the sort function with custom code
that evaluates the value of the "price" key in
each hash. Within each hash, the keys are sorted
alphabetically and then output with their corresponding
values.
We might spin-off the master carsforsale list into
a sub-list by manufacturer; for instance, a list of hashes
for only those cars made by Toyota.
@toyotas=();
foreach $car (@carsforsale)
{ if ($car->{make} eq "Toyota")
{ push(@toyotas,$car) }
}
The resulting toyotas list is simply a subset of the
original carsforsale list of hashes, and can be
managed or output the same way.
A List of Lists
The Perl You Need to Know
A Hash of Lists
|