user2079828
user2079828

Reputation: 655

hash arrays for basic Perl script

I'm writing my first Perl script and am reading a small text file line by line. The fields are delimited by ':' so i want to split each field into a hash array using the first field(name) as the key for each. Also, (I think) I want a big hash that holds all the information, or maybe just an array that holds each field so I can print all info on one line based on a pattern. I've not gotten far as %info is creating odd # elements in the hash assignment. Should I make it a regular array, and am I even going about this the right way? Basically, lines are in this order.

name:phone:address:date:salary
#!/usr/bin/perl -w

use strict;

print $#ARGV;

if($#ARGV == -1)
{
    print "Script needs 1 argument please.\n";
    exit 1;
}

my $inFILE = $ARGV[0];

#open the file passed
open(IN, "$inFILE") || die "Cannot open: $!"; #open databook.txt

my %info = (my %name, my %phone, my %address, my %date, my %salary);
while(<IN>)
{
    %info = (split /:/)[1];


}

close($inFILE);

Upvotes: 1

Views: 153

Answers (1)

Logan Ding
Logan Ding

Reputation: 1771

First of all, you should define your data structure depending on how you would use the information parsed. If you're using the name as index to search the information, I suggest to use a nested hash, indexed by the name:

{name => {phone => ..., address => ..., date => ..., salary => ...}, ...}

If you're not going to use name as index, just store the information in an array:

[ {name => ..., address => ..., date => ..., salary => ...}, 
  {name => ..., address => ..., date => ..., salary => ...}, ...]

In most cases I would use the first one.

Secondly, arrays and hashes in Perl are flat. So this:

my %info = (my %name, my %phone, my %address, my %date, my %salary);

doesn't make sense. Use a ref to store the data.

Last but not least, Perl has a syntax sugar for the input file. Use <> to read file from arguments, instead of opening files explicitly. This makes the program more "Perlish".

use strict;
use warnings;
use Data::Dumper;

my $info = {};
while (<>) {
    chomp;
    my @items = split /:/, $_;
    $info->{$items[0]} = { phone => $items[1], 
                           address => $items[2], 
                           date => $items[3], 
                           salary => $items[4] };
}

print Dumper $info;

Upvotes: 4

Related Questions