Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Reverse array reference?/please help me 1

Status
Not open for further replies.

sloppyhack

Technical User
Apr 17, 2001
111
US
Oh mighty perl scriptors,

Probably a simple task but I'm new to Perl (it rocks!) I am editing/validating tab delimited text with similar data in varying columns throughout the file and I need to be able to define which column data exist based on header rows. I can split the rows into arrays but then I need to somehow get the element number from an array to determine which column the data is in to apply the rest of the expressions. Example:

@array = qw(Color Size Height Length);
$array[how do I get this] = "Height";

I'm sure there is a way to do this as it seems like a common task. Any help would be greatly appreciated!!!

sloppyhack
 
I think you should look in hashes instead of arrays.

A hash can accept text and looks as follows:

$data{name} = "Thierry";




Thierry

 
so you've split the file into rows and now you want to turn each row into it's own array, ya? no problem. it's called a two-dimentional array. an array of arrays is what it really is. you can turn the file into one of these at any point, but you might as well do it when you first read it in. okay, here's what that'll look like:[tt]
open(FILE, "file.db") or die("File no open: $!");
my @file = ();
while (<FILE>)
{
push @file, [split(&quot;\t&quot;, $_)];
}
close FILE;[/tt]

notice the square brackets around the split function. what this does is create an anonymous array reference. the end result is that each line will have one entry in the @file array, the value of which will be that reference, a reference to an array comprised of the tab-delimited entries in each row.
now, a quick note on how to access these after the fact. read 'perldoc perlrefs'. but, to start you off, you can access the individual elements with something like this:[tt]
$file[0][0]; #the zeroth element of the zeroth row
$file[0][1]; #the one-th element of the zeroth row
$file[1][0]; #the zeroth element of the one-th row
[/tt]

so you call the row number first, then the element. you can access an idividual row like this:[tt]
@$file[0]; #the zeroth row in array form
@$file[1]; #the one-th row in array form[/tt]

definitely definitely read that perldoc entry if you want to do this correctly.
HTH &quot;If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito.&quot;
 
Thanks HTH,

Nice! I will definitely be able to use that functionality in my parser/validator though I am not sure it solves my problem. The issue is that similar data may be in different places in the row (array) throughout the file. The location of the data is redifined as each block of data is encountered. I need to somehow determine the location of elements in the header row array to determine how to apply my expressions. Maybe hashes would be a better approach but I doubt it. Here's an example of the data:

Color{tab}Size{tab}Height #defines locations
Blue{tab}Large{tab}Short
{blank line}
Size{tab}Color{tab}Height #defines locations
Small{tab}Green{tab}Tall

Thanks again,
sloppyhack
 
Thanks Thierry too. Forgot to mention you. Though I don't think that hashes are the solution, but what do I know?

Cheers,
Sloppyhack
 
actually, with that data structure, hashes could really be better. i didn't know you were redefining the keys as you went along... actually, sort of like a 2-D array would be an array of hash references, which would work even better.

erm, assuming that any one key entry can be followed by multiple entries for whom those keys will be true (in other words, blank line followed by keys can be followed by any number of same-format entries, followed again by a blank line. this cuts down on repeated key lines), the control structure for the reading in of the file might look something like this:[tt]
open(FILE, &quot;file.txt&quot;) or die(&quot;File no open: $!&quot;);
my @file = <FILE>;
close FILE;
my @formatted_data;
for (my $i = 0; $i < @file; $i++)
{
if ($file[$i] =~ /^\n?$/)
{
my @keys = split '\t', $file[++$i];
while (($file[$i+1] !~ /^\n?$/) && ($i+1 < @file))
{
my @tmp_keys = @keys;
my @entry = split '\t', $file[$i+1];
my %tmp_hash;
while (@tmp_keys)
{
$tmp_hash{shift @tmp_keys} = shift @entry;
}
push @formatted_data, \%tmp_hash;
$i++;
}
}
}[/tt]

i just threw this together, and it's untested, but it should give you the basic idea of what will be expected...i hope :)
the backslash on the front of '\%tmp_hash' is just another way to make a reference, not anonymous in this case, well, until %tmp_hash goes out of scope...
to access these (you've read the perldoc entry, right?), you can do something like the following:[tt]
$formatted_data[0]{'color'}; # the zeroth entry's color
%$formatted_data[1]; #the one-th hash
#etc.[/tt]
&quot;If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito.&quot;
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top