Arrays / Hashes / LoLs -- Building a data store

B

Ben B

All

I need to build something to store data. In its original form the
data looks like this --

Title File Level Content
---------------------------------------------------------------
"Home" "index.htm" 4 "Home Page"
"News" "news.htm" 1 "Welcome to the news"
"Contact" "id.htm" 3 "Contact me at..."

I have trawled Google and can't find the right structure for this data
-- a Hash, an Array, a List of Lists or so on -- I do know that Perl
does not have a true multi-dimensional array. I need to be able to
reference the line by the Title.

I am happy capturing each data element and dealing with it by chopping
up lines and elements, but what should I use to store this data, and
then reference it?

Any help appreciated -- I'd like an explanation, and suggestions,
rather than someone coding this for me out of the goodness of their
heart.

Regards

Ben
 
G

Gunnar Hjalmarsson

Ben said:
I need to build something to store data. In its original form the
data looks like this --

Title File Level Content
---------------------------------------------------------------
"Home" "index.htm" 4 "Home Page"
"News" "news.htm" 1 "Welcome to the news"
"Contact" "id.htm" 3 "Contact me at..."

I need to be able to reference the line by the Title.

It sounds like you want a hash, with the titles as keys.
I am happy capturing each data element and dealing with it by
chopping up lines and elements, but what should I use to store this
data, and then reference it?

Some thoughts follow:

One option is a one dimensional hash:

$hash{Home} = "index.htm\t4\tHome Page";

in which case you would need to split the value to access an
individual field.

Another option is a hash of arrays:

$hash{Home} = [ 'index.htm', 4, 'Home Page' ];

That way you would be able to access e.g. the content of the "Home"
record this way:

print $hash{Home}[2];

The first suggestion would make it possible to store the hash in a DBM
file, which is a simple but effective method.

The other suggestion would require some more sophisticated storage
method, and using the Storable module might be appropriate.
 
M

Master Web Surfer

[This followup was posted to comp.lang.perl.misc]

All

I need to build something to store data. In its original form the
data looks like this --

Title File Level Content
---------------------------------------------------------------
"Home" "index.htm" 4 "Home Page"
"News" "news.htm" 1 "Welcome to the news"
"Contact" "id.htm" 3 "Contact me at..."

I have trawled Google and can't find the right structure for this data
-- a Hash, an Array, a List of Lists or so on -- I do know that Perl
does not have a true multi-dimensional array. I need to be able to
reference the line by the Title.

I am happy capturing each data element and dealing with it by chopping
up lines and elements, but what should I use to store this data, and
then reference it?

Any help appreciated -- I'd like an explanation, and suggestions,
rather than someone coding this for me out of the goodness of their
heart.

Regards

Ben


The following code (tested under Win XP , perl 5.8.0) should point you
in the right direction.


#!/usr/bin/perl -w

# Title File Level Content
# ---------------------------------------------------------------
#
# "Home" "index.htm" 4 "Home Page"
# "News" "news.htm" 1 "Welcome to the news"
# "Contact" "id.htm" 3 "Contact me at..."


@array = ();
push @array, [ "Home" , "index.htm" , 4 , "Home Page"];
push @array, [ "News" , "news.htm" , 1 , "Welcome to the news"];
push @array, [ "Contact" , "id.htm" , 3 , "Home Page"];

print "Title File Level Content\n";
for ( $i = 0 ; $i <= $#array ; ++$i ) {
printf "%-14s %-13s %-11d %s\n",$array[$i][0],$array[$i][1],$array
[$i][2],$array[$i][3];
}

exit 0;
 
E

Eric Schwartz

I need to build something to store data. In its original form the
data looks like this --

Title File Level Content
---------------------------------------------------------------
"Home" "index.htm" 4 "Home Page"
"News" "news.htm" 1 "Welcome to the news"
"Contact" "id.htm" 3 "Contact me at..."

I have trawled Google and can't find the right structure for this data
-- a Hash, an Array, a List of Lists or so on -- I do know that Perl
does not have a true multi-dimensional array. I need to be able to
reference the line by the Title.

Seems like you want a Hash of Hashes, then:

my %hoh = ( "Home" => { File => "index.htm",
Level => 4,
Content => "Home Page" },
"News" => { File => "news.htm",
Level => 1,
Content => "Welcome to the news" },
.... );

# get the Level of the "Home" line:
my $level = $hoh{"Home"}{"Level"}

# what's the Content of the News line?
my $content = $hoh{"News"}{"Content"}
I am happy capturing each data element and dealing with it by chopping
up lines and elements, but what should I use to store this data, and
then reference it?

See above. To construct it, you'd loop over the data something like:

my %hoh = ();
while(<FILE>) {
my @fields = split;
$hoh{$fields[0]} = { File => $fields[1], Level => $fields[2],
Content => $fields[3] };
}

(untested, quite possibly buggy, and no attempt at error handling made)
Any help appreciated -- I'd like an explanation, and suggestions,
rather than someone coding this for me out of the goodness of their
heart.

Spend some time with 'perldoc perlref'; it should explain whatever I missed.

-=Eric
 
U

Uri Guttman

use strict ;

MWS> @array = ();
MWS> push @array, [ "Home" , "index.htm" , 4 , "Home Page"];
MWS> push @array, [ "News" , "news.htm" , 1 , "Welcome to the news"];
MWS> push @array, [ "Contact" , "id.htm" , 3 , "Home Page"];

why use push three times when one push could take all three array refs
as data? or why even push if you are just assigning them to @array?

my @array = (
[ "Home" , "index.htm" , 4 , "Home Page"],
[ "News" , "news.htm" , 1 , "Welcome to the news"],
[ "Contact" , "id.htm" , 3 , "Home Page"],
) ;


MWS> for ( $i = 0 ; $i <= $#array ; ++$i ) {

gack! c style loops are so not perlish.

foreach my $aref ( @array )

MWS> printf "%-14s %-13s %-11d %s\n",$array[$i][0],$array[$i][1],$array
MWS> [$i][2],$array[$i][3];
MWS> }

now that we have an array ref for a given row, we can just pass all the
args in one list. no need for the [0], etc. this is the perl way to scan
lists of lists.

printf "%-14s %-13s %-11d %s\n", @{$aref} ;

uri
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,141
Messages
2,570,818
Members
47,367
Latest member
mahdiharooniir

Latest Threads

Top