Priyanka Agarwal
Priyanka Agarwal

Reputation: 9

How to refer each column of a text file by hash in perl

I am having a file which is storing the result of a query separated by | (pipe sign). I want each column to be refereed by a hash.

eg. the f.txt file containment is:

aaa|bbb|ccc  
ddd|eee|fff  
ggg|hhh|iii

I need the o/p as:

a{a}=> {aaa,ddd,ccc}  
a{b}=> {bbb,eee,hhh}  
a{c}=> {ccc,fff,iii}

Please advice on the same.

Upvotes: 0

Views: 135

Answers (1)

David W.
David W.

Reputation: 107040

I think you'd be better off representing your data as an Array of Array instead of a Hash of Hashes. This is because you don't have any idea what your keys are. An array is an ordered list of data, and you can at least refer to a particular row and column of your data this way without making up keys for it.

If you know the names of your columns, you might want an Array of Hashes instead. This way, you can refer to a particular row with its element number in the array, but refer to the column with via a name.

This is using an Array of Arrays:

use strict;
use warnings;
use autodie;
use feature qw(say);

use constant {
    FILE_NAME => "...",
};

open my $fh, "<", FILE_NAME;

#
#  This builds your Array of Arrays
#

my @file_contents;
while ( my $row = <$fh> ) {
    chomp $row;
    push @file_contents, split /\s*\|\s*/, $row;
}

#
# We count from 1, but arrays count from zero. That's why array indexes
# are one less than the row and column I am referring to.
#
say "The first row and second column is " . $file_contents[0]->[1];
say "The third row and third column is " .  $file_contents[2]->[2];

#
# This reprints entire file with the separators
#

for my $row ( @file_contents ) {
    @columns = @{ $row };
    say join "|", @columns;
}

Addendum

I am aware of what are my columns and my hash key also. I need to pass this o/p to an inbuilt API which takes the parameter as hash only. So cant really store the data in the array.

Are you saying that your columns are a hash with the column names being the hash key? This makes sense. If you're saying that each ROW has its own key, you have to give me an idea what that is, and where it comes from.

Here's a solution that creates your file contents in an array called @file_contents. It contains a reference to a hash representing each row of data with the key being the column name and the value being the data of that column. You can then use this hash to update via your API:

This is done in two loops: One filling up @file_contents and another using your API (however that's done). There's no reason why it can't be done in a single loop.

use strict;
use warnings;
use autodie;
use feature qw(say);

use constant {
    FILE_NAME => "...",
};

# Names of the columns
my @column_names = qw( foo bar barfu fubar foofoo barbar );

open my $fh, "<", FILE_NAME;

#
#  This builds your Array of Column hashes
#

my @file_contents;
while ( my $row = <$fh> ) {
    chomp $row;
    @cols =  split /\s*\|\s*/, $row;
    my %col_hash;
    for $col_num ( 0.. $#file_contents ) {
       %col_hash{ $col_name[ $col_num ] } = $cols[ $column_num ];
    }
    push @file_contents, \%col_hash;
}

for my $cols_ref ( @file_contents ) {
    my %col_hash = %{ $cols_ref };
    API_CALL (..., ..., %col_hash );
}

If this is truly a hash of hashes, that is the rows of your table are hash entries, you've got to let me know where the keys come from. It's very possible that the first column of your table is the key to the rest of the data. For example, let's say your table looks like this:

 Visitors in thousands

city  |jan |apr |july|oct|
Duluth|0   |0   |0   |0
NYC   |500 |1200|1500|600
Miami |1200|1600|2300|200

I can imagine the city being the key to each row, and the month being the key to each column. I could talk about this:

say "The number of people in NYC in July is " . $visitors{NYC}->{july};

Is this the case with your data? If not, what is the key to your hash? Certainly, I'm not suppose to make up random values for the hash keys.

You've got to give a clearer description what you need.

Upvotes: 1

Related Questions