CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
Representing Table in Perl

 



zachlac
Novice

Apr 25, 2007, 8:12 AM

Post #1 of 10 (1209 views)
Representing Table in Perl Can't Post

I am trying to use Perl for this for the first time, since it seems to be well-suited for the task. My problem is this: I have a table of unknown length, located in a normal text file. Each row has 6 fields separated by tab characters, finished with a newline character. I want to read this table into some type of data structure, then be able to sort it by any of the six fields. My end goal is that the user can run the script, specify an input file, then type in commands such as "sort <field name>" and have the script change the data structure to be sorted by whatever that field was.

In C++ I would simply use a linked list to accomplish this, but I think it would be easier to do in Perl if only I could figure out how to store it! Thanks.


osmodius
Novice

Apr 25, 2007, 8:56 AM

Post #2 of 10 (1206 views)
Re: [zachlac] Representing Table in Perl [In reply to] Can't Post

Best idea is to have the equivalent to a multidimensional array, i.e. an array containing hash references.


Need some real-time help? Shove admin@ub3r.net on yer MSN.


KevinR
Veteran


Apr 25, 2007, 11:18 AM

Post #3 of 10 (1203 views)
Re: [zachlac] Representing Table in Perl [In reply to] Can't Post

Yes, an array of arrays or other multidimensional data structure sounds appropriate, then sort by which ever field/column/index/key (depends on how you structure the data) you want to, or sort on multiple fields.

Some tutorials here on complex data stuctures (the first 3):

http://perldoc.perl.org/index-tutorials.html


If this data is often sorted or there is a lot of data , you could create pre sorted files, indexes if you will, and when the user selects the field to sort by, the corresponding index is opened and read instead of always sorting the data on the fly. If data is added or removed, resort the files at that time only.
-------------------------------------------------


zachlac
Novice

Apr 25, 2007, 11:56 AM

Post #4 of 10 (1202 views)
Re: [KevinR] Representing Table in Perl [In reply to] Can't Post

Thank you both for your help. Basically, what I'm hearing is that I can make a hash with the ItemID as the key, and an array of length 5 as the value, containing the 5 different other properties. Since the items are most likely to be sorted by ItemID, this seems to be the best way to go about this.

One other question: in Perl, if I create a hash with both a key and a value represented by a temporary changing value and array, will the program create new instances of the variables for each spot in the hash, or will it refer to the spots by reference? Basically, can I use two temporary variables which change with each iteration through the while loop reading in the file, or will this result in a hash with each set of variables being the same? Thanks.


KevinR
Veteran


Apr 25, 2007, 12:06 PM

Post #5 of 10 (1200 views)
Re: [zachlac] Representing Table in Perl [In reply to] Can't Post

hash keys can only be strings, so they can't change. The values of the hash keys can change while building up a hash it thats what you mean. Maybe provide an example if I didn't uderstand your question.
-------------------------------------------------


zachlac
Novice

Apr 25, 2007, 12:12 PM

Post #6 of 10 (1199 views)
Re: [KevinR] Representing Table in Perl [In reply to] Can't Post

Here's an example of what I've written. INFILE is an open file stream, and $a has been declared previously. %table is the hash I am using.

while ($a = <INFILE>)
{
#temporary variables for working with the input
my ($temp, @arr);
@arr = split (/'\t'/, $a);

#removes the first element, which is the key
$temp = unshift(@arr);

$table{$temp} = @arr;

}


KevinR
Veteran


Apr 25, 2007, 12:24 PM

Post #7 of 10 (1197 views)
Re: [zachlac] Representing Table in Perl [In reply to] Can't Post

start using "strict" and "warnings" in all your perl scripts. Avoid using $a and $b in your scripts except for sorting data, they are special variables used by perl internally for sorting.


Code
use strict; 
use warnings;
use Data::Dumper;#great for printing complex data

my %table = (); #declare an empty hash
#assumes you open the file here
while (my $line = <INFILE>) {
chomp($line); #remove the input record seperator
my @arr = split (/\t/, $line);
$table{$arr[0]} = [@arr[1..$#arr]];
}
close(INFILE);
print Dumper \%table;


that will create a hash or annonymous arrays. This will not do what you think:


Code
 $table{$temp} = @arr;


$table{$temp} is a scalar, assigning the value of an array to a scalar returns the length of the array not the content of the array.
-------------------------------------------------


zachlac
Novice

Apr 25, 2007, 1:03 PM

Post #8 of 10 (1195 views)
Re: [KevinR] Representing Table in Perl [In reply to] Can't Post

Thanks. I forgot the array length thing. How then can I set the value of the hash to be an array instead of a string? Or is that not valid in Perl?

EDIT: I found this syntax on another Perl help website: if I use the assignment $table{$temp} = \@arr, then it preserves the array. Thus, I can refer to elements using the syntax $table{$key}[0].


(This post was edited by zachlac on Apr 25, 2007, 2:13 PM)


KevinR
Veteran


Apr 25, 2007, 2:33 PM

Post #9 of 10 (1191 views)
Re: [zachlac] Representing Table in Perl [In reply to] Can't Post


In Reply To
Thanks. I forgot the array length thing. How then can I set the value of the hash to be an array instead of a string? Or is that not valid in Perl?


The code I posted does that:


Code
$table{$arr[0]} = [ @arr[1..$#arr] ];


the square brackets around @arr[] create an annonymous array. The other way is to use a reference:


Code
$table{$temp} = \@arr;



which way you do it in this situation probably does not matter. But using the second form \@arr is a reference back to the original data and will affect the original data (if there is any to be affected). The way I did it creates a copy of the data that would never affect the original data. Sometimes you want to affect the original data and sometimes you don't. Here is an example:


Code
@array = qw(foo bar baz); 
my $ref = \@array;
$ref->[1] = 'cow';
print "@array\n";

@array2 = qw(foo bar baz);
my $ref2 = [@array2];
$ref2->[1] = 'bat';
print "@array2";


output:


Code
foo cow baz 
foo bar baz


as you can see the first method changes the orginal array the reference points to. In the second it does not. This can lead to much confusion if you are not aware of this behavior. But like I said, either way wil work for what you are doing.
-------------------------------------------------


zachlac
Novice

Apr 25, 2007, 2:57 PM

Post #10 of 10 (1190 views)
Re: [KevinR] Representing Table in Perl [In reply to] Can't Post

Thank you for your help. One last question: after declaring the hash using your method, can I refer to it using the method of $table{$var}[0..4]?

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives