Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi all,

I am trying to parse information from multiple files for some feilds.

My objective is to make a matrix out of those feilds. for exanple:I have 3 feilds with queryname,subject name and percent ID.

I want to print in an excel sheet
Qname1 Qname2 Subname1 percent ID1 percent ID2
I am trying to catch the Qname,Sname and Ids in a ID hash:
push(@{$idmatrix{$qname}},$qname[$q]); push(@{$idmatrix{$id[$q][$s]}},$id); push(@{$idmatrix{$sname}},$sname[$s]);
I am unable to figureout how to print them in the format i wanted.

Also how to avoid repeated names in the hash;

Please ...please help me.

Thanks

Replies are listed 'Best First'.
Re: HASH HELP PLEASE
by pc88mxer (Vicar) on Jun 01, 2008 at 16:34 UTC
    Also have a look at Text::Table.

    As for capturing the data, I think just a HoH will suffice. Your matrix presentation suggests that for each query and subject only one percent value is possible. In pseudo code:

    my $matrix; my %seen_queries; for each row in the excel file: my ($query, $subject, $percent) = values from the excel row $matrix->{$subject}->{$query} = $percent; $seen_queries{$query} = 1; end for
    And to display the matrix:
    use Text::Table; my @cols = keys %seen_queries; my $tb = Text::Table->new(@cols); for my $subject (keys %$matrix) { $tb->load( [ @{$matrix->{$subject}}{@cols} ] ); } print $tb;
    This code demonstrates:
    • the use of a hash to keep track of seen identifiers (%seen_queries)
    • using a HoH to store a 2-D matrix of data
    • hash slices to conveniently extract multiple values from a hash at once
    Also, when writing this code I had to decide if I wanted to store the data as $matrix->{$subject}->{$query} or $matrix->{$query}->{$subject}. The latter organization would still work but would have made the table display code slightly more complex. Here's how it would have worked out:
    use Text::Table; my @cols = keys %$matrix; my $tb = Text::Table->new(@cols); for my $subject (keys %seen_subjects) { my @vals; for my $query {@cols) { push(@vals, $matrix->{$query}->{$subject}); } $tb->load( [ @vals ] ); }
    The hash %seen_subjects would be constructed in the reading phase just like %seen_queries but with $subject as the hash parameter.
Re: HASH HELP PLEASE
by apl (Monsignor) on Jun 01, 2008 at 16:09 UTC
    For the report, you need to read up on Perl formats. They'll help you produce exactly what you need. (If you have questions after you read this, I'll be happy to provide specific answers).

    As far as how to store the information, I think you'd be better served by a Hash Of Hashes of Hashes, e.g. $idmatrix{$subname1}{$qName1}{$qName2}, or $idmatrix{Whoopie}{Cog}{Cogswell}.

    That way, when it comes time to display your table you can just have a series of foreach my $name ( sorted keys %idmatrix } etc.

    (The code snippets have not been tested, and random "s"s may have been added ot dropped; sorry.)

      Looks like a way to go... can be more specific,I am new to hashes. Since I could'nt deal with this woth 2D arrys,turned on to hashes. How do I assign values:to hash of hash of hash and how the hell i print it? Looks like they are not in the order.... please help me.

        Hashes are, by definition, unordered (or rather, not in an order you would think of :). If you need them sorted, then see the keys() and sort() functions.

        You may want to also search for HoHoH

        --MidLifeXis

        You can think of a hash as being like an array, only using a unique string as a key rather than a unique number as an index. (push adds an element at the end of an array, so you never need to know the index. With a hash, you have to explicitly specify what the key is, as in for example, "Sample 17".)

        Take a minute and read the Data Type: Hash tutorials. Again, if you have explicit questions, don't hesitate to ask.

        Have a read of the PDSC (Perl Data Structures Cookbook).
Re: HASH HELP PLEASE
by pc88mxer (Vicar) on Jun 01, 2008 at 18:17 UTC
    Up in this thread you mentioned that you wabt to keep track of the the order in which you see queries and subjects. An old recipe for this is to use both an array and a hash:
    my %seen_subject; my @subjects_seen; ... # $s is a subject read from the excel file if (! $seen_subject{$s}++) { push(@subjects_seen, $s); } ...
    Alternatively, look into Tie::Hash::Indexed which will return keys in the order in which they were created.